Compare commits

..

5 Commits

Author SHA1 Message Date
dfdc31512d App with extension functions
All checks were successful
Build on push / prepare (push) Successful in 9s
Build on push / core (push) Successful in 17s
Build on push / query (push) Successful in 17s
Build on push / dependency (push) Successful in 14s
Build on push / translation (push) Successful in 14s
Build on push / database (push) Successful in 18s
Build on push / mail (push) Successful in 19s
Build on push / application (push) Successful in 22s
Build on push / auth (push) Successful in 14s
2025-09-17 21:56:47 +02:00
ab7ff7da93 Made startup/app extensions static 2025-09-17 20:54:21 +02:00
41087a838b Removed pass from empty functions
All checks were successful
Build on push / prepare (push) Successful in 9s
Build on push / core (push) Successful in 17s
Build on push / query (push) Successful in 17s
Build on push / dependency (push) Successful in 17s
Build on push / translation (push) Successful in 14s
Build on push / mail (push) Successful in 18s
Build on push / database (push) Successful in 18s
Build on push / application (push) Successful in 24s
Build on push / auth (push) Successful in 14s
2025-09-17 20:49:15 +02:00
836b92ccbf Further console test 2025-09-17 20:44:25 +02:00
8aaba22940 Improved application structure
All checks were successful
Build on push / prepare (push) Successful in 11s
Build on push / core (push) Successful in 22s
Build on push / query (push) Successful in 22s
Build on push / dependency (push) Successful in 20s
Build on push / database (push) Successful in 20s
Build on push / translation (push) Successful in 20s
Build on push / application (push) Successful in 22s
Build on push / mail (push) Successful in 23s
Build on push / auth (push) Successful in 16s
2025-09-17 19:23:14 +02:00
69 changed files with 367 additions and 642 deletions

View File

@@ -1,6 +1 @@
from .application_abc import ApplicationABC
from .application_builder import ApplicationBuilder from .application_builder import ApplicationBuilder
from .application_builder_abc import ApplicationBuilderABC
from .application_extension_abc import ApplicationExtensionABC
from .startup_abc import StartupABC
from .startup_extension_abc import StartupExtensionABC

View File

@@ -0,0 +1,4 @@
from .application_abc import ApplicationABC
from .application_extension_abc import ApplicationExtensionABC
from .startup_abc import StartupABC
from .startup_extension_abc import StartupExtensionABC

View File

@@ -0,0 +1,73 @@
from abc import ABC, abstractmethod
from typing import Callable, Self
from cpl.application.host import Host
from cpl.core.console.console import Console
from cpl.dependency.service_provider_abc import ServiceProviderABC
def __not_implemented__(package: str, func: Callable):
raise NotImplementedError(f"Package {package} is required to use {func.__name__} method")
class ApplicationABC(ABC):
r"""ABC for the Application class
Parameters:
services: :class:`cpl.dependency.service_provider_abc.ServiceProviderABC`
Contains instances of prepared objects
"""
@abstractmethod
def __init__(self, services: ServiceProviderABC):
self._services = services
@classmethod
def extend(cls, name: str | Callable, func: Callable[[Self], Self]):
r"""Extend the Application with a custom method
Parameters:
name: :class:`str`
Name of the method
func: :class:`Callable[[Self], Self]`
Function that takes the Application as a parameter and returns it
"""
if callable(name):
name = name.__name__
setattr(cls, name, func)
return cls
def with_permissions(self, *args, **kwargs):
__not_implemented__("cpl-auth", self.with_permissions)
def with_migrations(self, *args, **kwargs):
__not_implemented__("cpl-database", self.with_migrations)
def with_seeders(self, *args, **kwargs):
__not_implemented__("cpl-database", self.with_seeders)
def with_extension(self, func: Callable[[Self, ...], None], *args, **kwargs):
r"""Extend the Application with a custom method
Parameters:
func: :class:`Callable[[Self], Self]`
Function that takes the Application as a parameter and returns it
"""
assert func is not None, "func must not be None"
assert callable(func), "func must be callable"
func(self, *args, **kwargs)
def run(self):
r"""Entry point
Called by custom Application.main
"""
try:
Host.run(self.main)
except KeyboardInterrupt:
Console.close()
@abstractmethod
def main(self): ...

View File

@@ -0,0 +1,10 @@
from abc import ABC, abstractmethod
from cpl.dependency import ServiceProviderABC
class ApplicationExtensionABC(ABC):
@staticmethod
@abstractmethod
def run(services: ServiceProviderABC): ...

View File

@@ -3,19 +3,17 @@ from abc import ABC, abstractmethod
from cpl.dependency.service_collection import ServiceCollection from cpl.dependency.service_collection import ServiceCollection
class AsyncStartupABC(ABC): class StartupABC(ABC):
r"""ABC for the startup class""" r"""ABC for the startup class"""
@staticmethod
@abstractmethod @abstractmethod
def __init__(self): def configure_configuration():
pass
@abstractmethod
async def configure_configuration(self):
r"""Creates configuration of application""" r"""Creates configuration of application"""
@staticmethod
@abstractmethod @abstractmethod
async def configure_services(self, service: ServiceCollection): def configure_services(service: ServiceCollection):
r"""Creates service provider r"""Creates service provider
Parameter: Parameter:

View File

@@ -0,0 +1,20 @@
from abc import ABC, abstractmethod
from cpl.dependency import ServiceCollection
class StartupExtensionABC(ABC):
r"""ABC for startup extension classes"""
@staticmethod
@abstractmethod
def configure_configuration():
r"""Creates configuration of application"""
@staticmethod
@abstractmethod
def configure_services(services: ServiceCollection):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection`
"""

View File

@@ -1,57 +0,0 @@
from abc import ABC, abstractmethod
from typing import Optional
from cpl.dependency.service_provider_abc import ServiceProviderABC
from cpl.core.console.console import Console
class ApplicationABC(ABC):
r"""ABC for the Application class
Parameters:
config: :class:`cpl.core.configuration.configuration_abc.ConfigurationABC`
Contains object loaded from appsettings
services: :class:`cpl.dependency.service_provider_abc.ServiceProviderABC`
Contains instances of prepared objects
"""
@abstractmethod
def __init__(self, services: ServiceProviderABC):
self._services: Optional[ServiceProviderABC] = services
def run(self):
r"""Entry point
Called by custom Application.main
"""
try:
self.configure()
self.main()
except KeyboardInterrupt:
Console.close()
async def run_async(self):
r"""Entry point
Called by custom Application.main
"""
try:
await self.configure()
await self.main()
except KeyboardInterrupt:
Console.close()
@abstractmethod
def configure(self):
r"""Configure the application
Called by :class:`cpl.application.application_abc.ApplicationABC.run`
"""
@abstractmethod
def main(self):
r"""Custom entry point
Called by :class:`cpl.application.application_abc.ApplicationABC.run`
"""

View File

@@ -1,97 +1,64 @@
from typing import Type, Optional, Callable, Union import asyncio
from typing import Type, Optional
from cpl.application.application_abc import ApplicationABC from cpl.application.abc.application_abc import ApplicationABC
from cpl.application.application_builder_abc import ApplicationBuilderABC from cpl.application.abc.application_extension_abc import ApplicationExtensionABC
from cpl.application.application_extension_abc import ApplicationExtensionABC from cpl.application.abc.startup_abc import StartupABC
from cpl.application.async_application_extension_abc import AsyncApplicationExtensionABC from cpl.application.abc.startup_extension_abc import StartupExtensionABC
from cpl.application.async_startup_abc import AsyncStartupABC from cpl.application.host import Host
from cpl.application.async_startup_extension_abc import AsyncStartupExtensionABC
from cpl.application.startup_abc import StartupABC
from cpl.application.startup_extension_abc import StartupExtensionABC
from cpl.core.configuration.configuration import Configuration
from cpl.dependency.service_collection import ServiceCollection from cpl.dependency.service_collection import ServiceCollection
from cpl.core.environment import Environment
class ApplicationBuilder(ApplicationBuilderABC): class ApplicationBuilder:
r"""This is class is used to build an object of :class:`cpl.application.application_abc.ApplicationABC` r"""A builder for constructing an application with configurable services and extensions."""
Parameter:
app: Type[:class:`cpl.application.application_abc.ApplicationABC`]
Application to build
"""
def __init__(self, app: Type[ApplicationABC]): def __init__(self, app: Type[ApplicationABC]):
ApplicationBuilderABC.__init__(self) assert app is not None, "app must not be None"
self._app = app assert issubclass(app, ApplicationABC), "app must be an subclass of ApplicationABC or its subclass"
self._startup: Optional[StartupABC | AsyncStartupABC] = None
self._app = app if app is not None else ApplicationABC
self._services = ServiceCollection() self._services = ServiceCollection()
self._app_extensions: list[Type[ApplicationExtensionABC | AsyncApplicationExtensionABC]] = [] self._startup: Optional[StartupABC] = None
self._startup_extensions: list[Type[StartupExtensionABC | AsyncStartupABC]] = [] self._app_extensions: list[Type[ApplicationExtensionABC]] = []
self._startup_extensions: list[Type[StartupExtensionABC]] = []
def use_startup(self, startup: Type[StartupABC | AsyncStartupABC]) -> "ApplicationBuilder": self._async_loop = asyncio.get_event_loop()
self._startup = startup()
@property
def services(self) -> ServiceCollection:
return self._services
@property
def service_provider(self):
return self._services.build()
def with_startup(self, startup: Type[StartupABC]) -> "ApplicationBuilder":
self._startup = startup
return self return self
def use_extension( def with_extension(
self, self,
extension: Type[ extension: Type[ApplicationExtensionABC | StartupExtensionABC],
ApplicationExtensionABC | AsyncApplicationExtensionABC | StartupExtensionABC | AsyncStartupExtensionABC
],
) -> "ApplicationBuilder": ) -> "ApplicationBuilder":
if ( if (issubclass(extension, ApplicationExtensionABC)) and extension not in self._app_extensions:
issubclass(extension, ApplicationExtensionABC) or issubclass(extension, AsyncApplicationExtensionABC)
) and extension not in self._app_extensions:
self._app_extensions.append(extension) self._app_extensions.append(extension)
elif ( elif (issubclass(extension, StartupExtensionABC)) and extension not in self._startup_extensions:
issubclass(extension, StartupExtensionABC) or issubclass(extension, AsyncStartupExtensionABC)
) and extension not in self._startup_extensions:
self._startup_extensions.append(extension) self._startup_extensions.append(extension)
return self return self
def _build_startup(self):
for ex in self._startup_extensions:
extension = ex()
extension.configure_configuration(Configuration, Environment)
extension.configure_services(self._services, Environment)
if self._startup is not None:
self._startup.configure_configuration(Configuration, Environment)
self._startup.configure_services(self._services, Environment)
async def _build_async_startup(self):
for ex in self._startup_extensions:
extension = ex()
await extension.configure_configuration(Configuration, Environment)
await extension.configure_services(self._services, Environment)
if self._startup is not None:
await self._startup.configure_configuration(Configuration, Environment)
await self._startup.configure_services(self._services, Environment)
def build(self) -> ApplicationABC: def build(self) -> ApplicationABC:
self._build_startup() for extension in self._startup_extensions:
Host.run(extension.configure_configuration)
Host.run(extension.configure_services, self._services)
config = Configuration if self._startup is not None:
services = self._services.build_service_provider() Host.run(self._startup.configure_configuration)
Host.run(self._startup.configure_services, self._services)
for ex in self._app_extensions: for extension in self._app_extensions:
extension = ex() Host.run(extension.run, self.service_provider)
extension.run(config, services)
return self._app(services) return self._app(self.service_provider)
async def build_async(self) -> ApplicationABC:
await self._build_async_startup()
config = Configuration
services = self._services.build_service_provider()
for ex in self._app_extensions:
extension = ex()
await extension.run(config, services)
return self._app(services)

View File

@@ -1,47 +0,0 @@
from abc import ABC, abstractmethod
from typing import Type
from cpl.application.application_abc import ApplicationABC
from cpl.application.startup_abc import StartupABC
class ApplicationBuilderABC(ABC):
r"""ABC for the :class:`cpl.application.application_builder.ApplicationBuilder`"""
@abstractmethod
def __init__(self, *args):
pass
@abstractmethod
def use_startup(self, startup: Type[StartupABC]):
r"""Sets the custom startup class to use
Parameter:
startup: Type[:class:`cpl.application.startup_abc.StartupABC`]
Startup class to use
"""
@abstractmethod
async def use_startup(self, startup: Type[StartupABC]):
r"""Sets the custom startup class to use async
Parameter:
startup: Type[:class:`cpl.application.startup_abc.StartupABC`]
Startup class to use
"""
@abstractmethod
def build(self) -> ApplicationABC:
r"""Creates custom application object
Returns:
Object of :class:`cpl.application.application_abc.ApplicationABC`
"""
@abstractmethod
async def build_async(self) -> ApplicationABC:
r"""Creates custom application object async
Returns:
Object of :class:`cpl.application.application_abc.ApplicationABC`
"""

View File

@@ -1,14 +0,0 @@
from abc import ABC, abstractmethod
from cpl.core.configuration.configuration import Configuration
from cpl.dependency import ServiceProviderABC
class ApplicationExtensionABC(ABC):
@abstractmethod
def __init__(self):
pass
@abstractmethod
def run(self, config: Configuration, services: ServiceProviderABC):
pass

View File

@@ -1,14 +0,0 @@
from abc import ABC, abstractmethod
from cpl.core.configuration.configuration import Configuration
from cpl.dependency import ServiceProviderABC
class AsyncApplicationExtensionABC(ABC):
@abstractmethod
def __init__(self):
pass
@abstractmethod
async def run(self, config: Configuration, services: ServiceProviderABC):
pass

View File

@@ -1,31 +0,0 @@
from abc import ABC, abstractmethod
from cpl.core.configuration.configuration import Configuration
from cpl.dependency.service_collection import ServiceCollection
from cpl.core.environment.environment import Environment
class AsyncStartupExtensionABC(ABC):
r"""ABC for startup extension classes"""
@abstractmethod
def __init__(self):
pass
@abstractmethod
async def configure_configuration(self, config: Configuration, env: Environment):
r"""Creates configuration of application
Parameter:
config: :class:`cpl.core.configuration.configuration_abc.Configuration`
env: :class:`cpl.core.environment.application_environment_abc`
"""
@abstractmethod
async def configure_services(self, service: ServiceCollection, env: Environment):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection`
env: :class:`cpl.core.environment.application_environment_abc`
"""

View File

@@ -0,0 +1,17 @@
import asyncio
from typing import Callable
class Host:
_loop = asyncio.get_event_loop()
@classmethod
def get_loop(cls):
return cls._loop
@classmethod
def run(cls, func: Callable, *args, **kwargs):
if asyncio.iscoroutinefunction(func):
return cls._loop.run_until_complete(func(*args, **kwargs))
return func(*args, **kwargs)

View File

@@ -1,31 +0,0 @@
from abc import ABC, abstractmethod
from cpl.core.configuration import Configuration
from cpl.dependency.service_collection import ServiceCollection
from cpl.core.environment import Environment
class StartupABC(ABC):
r"""ABC for the startup class"""
@abstractmethod
def __init__(self):
pass
@abstractmethod
def configure_configuration(self, config: Configuration, env: Environment):
r"""Creates configuration of application
Parameter:
config: :class:`cpl.core.configuration.configuration_abc.ConfigurationABC`
env: :class:`cpl.core.environment.application_environment_abc`
"""
@abstractmethod
def configure_services(self, service: ServiceCollection, env: Environment):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection`
env: :class:`cpl.core.environment.application_environment_abc`
"""

View File

@@ -1,33 +0,0 @@
from abc import ABC, abstractmethod
from cpl.core.configuration import Configuration
from cpl.dependency.service_collection import ServiceCollection
from cpl.core.environment.environment import Environment
class StartupExtensionABC(ABC):
r"""ABC for startup extension classes"""
@abstractmethod
def __init__(self):
pass
@abstractmethod
def configure_configuration(self, config: Configuration, env: Environment):
r"""Creates configuration of application
Parameter:
config: :class:`cpl.core.configuration.configuration_abc.ConfigurationABC`
env: :class:`cpl.core.environment.application_environment_abc`
"""
@abstractmethod
def configure_services(self, service: ServiceCollection, env: Environment):
r"""Creates service provider
Parameter:
services: :class:`cpl.dependency.service_collection`
env: :class:`cpl.core.environment.application_environment_abc`
"""

View File

@@ -1,13 +1,24 @@
from cpl.auth import permission as _permission from enum import Enum
from cpl.auth.keycloak.keycloak_admin import KeycloakAdmin from typing import Type
from cpl.auth.keycloak.keycloak_client import KeycloakClient
from cpl.dependency import ServiceCollection as _ServiceCollection
from cpl.application.abc import ApplicationABC as _ApplicationABC
from cpl.auth import permission as _permission
from cpl.auth.keycloak.keycloak_admin import KeycloakAdmin as _KeycloakAdmin
from cpl.auth.keycloak.keycloak_client import KeycloakClient as _KeycloakClient
from cpl.dependency.service_collection import ServiceCollection as _ServiceCollection
from .auth_logger import AuthLogger from .auth_logger import AuthLogger
from .keycloak_settings import KeycloakSettings from .keycloak_settings import KeycloakSettings
from .permission_seeder import PermissionSeeder from .permission_seeder import PermissionSeeder
def _with_permissions(self: _ApplicationABC, *permissions: Type[Enum]) -> _ApplicationABC:
from cpl.auth.permission.permissions_registry import PermissionsRegistry
for perm in permissions:
PermissionsRegistry.with_enum(perm)
return self
def _add_daos(collection: _ServiceCollection): def _add_daos(collection: _ServiceCollection):
from .schema._administration.auth_user_dao import AuthUserDao from .schema._administration.auth_user_dao import AuthUserDao
from .schema._administration.api_key_dao import ApiKeyDao from .schema._administration.api_key_dao import ApiKeyDao
@@ -34,12 +45,12 @@ def add_auth(collection: _ServiceCollection):
from cpl.database.model.server_type import ServerType, ServerTypes from cpl.database.model.server_type import ServerType, ServerTypes
try: try:
collection.add_singleton(KeycloakClient) collection.add_singleton(_KeycloakClient)
collection.add_singleton(KeycloakAdmin) collection.add_singleton(_KeycloakAdmin)
_add_daos(collection) _add_daos(collection)
provider = collection.build_service_provider() provider = collection.build()
migration_service: MigrationService = provider.get_service(MigrationService) migration_service: MigrationService = provider.get_service(MigrationService)
if ServerType.server_type == ServerTypes.POSTGRES: if ServerType.server_type == ServerTypes.POSTGRES:
migration_service.with_directory( migration_service.with_directory(
@@ -68,3 +79,4 @@ def add_permission(collection: _ServiceCollection):
_ServiceCollection.with_module(add_auth, __name__) _ServiceCollection.with_module(add_auth, __name__)
_ServiceCollection.with_module(add_permission, _permission.__name__) _ServiceCollection.with_module(add_permission, _permission.__name__)
_ApplicationABC.extend(_ApplicationABC.with_permissions, _with_permissions)

View File

@@ -5,7 +5,7 @@ from typing import Optional
from async_property import async_property from async_property import async_property
from keycloak import KeycloakGetError from keycloak import KeycloakGetError
from cpl.auth import KeycloakAdmin from cpl.auth.keycloak import KeycloakAdmin
from cpl.auth.auth_logger import AuthLogger from cpl.auth.auth_logger import AuthLogger
from cpl.auth.permission.permissions import Permissions from cpl.auth.permission.permissions import Permissions
from cpl.core.typing import SerialId from cpl.core.typing import SerialId

View File

@@ -2,4 +2,6 @@ from abc import ABC
class ConfigurationModelABC(ABC): class ConfigurationModelABC(ABC):
pass r"""
ABC for configuration model classes
"""

View File

@@ -7,12 +7,10 @@ class LoggerABC(ABC):
r"""ABC for :class:`cpl.core.log.logger_service.Logger`""" r"""ABC for :class:`cpl.core.log.logger_service.Logger`"""
@abstractmethod @abstractmethod
def set_level(self, level: str): def set_level(self, level: str): ...
pass
@abstractmethod @abstractmethod
def _format_message(self, level: str, timestamp, *messages: Messages) -> str: def _format_message(self, level: str, timestamp, *messages: Messages) -> str: ...
pass
@abstractmethod @abstractmethod
def header(self, string: str): def header(self, string: str):

View File

@@ -7,10 +7,8 @@ from cpl.core.typing import T
class PipeABC(ABC, Generic[T]): class PipeABC(ABC, Generic[T]):
@staticmethod @staticmethod
@abstractmethod @abstractmethod
def to_str(value: T, *args) -> str: def to_str(value: T, *args) -> str: ...
pass
@staticmethod @staticmethod
@abstractmethod @abstractmethod
def from_str(value: str, *args) -> T: def from_str(value: str, *args) -> T: ...
pass

View File

@@ -1,11 +1,31 @@
from typing import Type from typing import Type
from cpl.application.abc import ApplicationABC as _ApplicationABC
from cpl.dependency import ServiceCollection as _ServiceCollection from cpl.dependency import ServiceCollection as _ServiceCollection
from . import mysql as _mysql from . import mysql as _mysql
from . import postgres as _postgres from . import postgres as _postgres
from .table_manager import TableManager from .table_manager import TableManager
def _with_migrations(self: _ApplicationABC, *paths: list[str]) -> _ApplicationABC:
from cpl.application.host import Host
from cpl.database.service.migration_service import MigrationService
migration_service = self._services.get_service(MigrationService)
migration_service.with_directory("./scripts")
Host.run(migration_service.migrate)
return self
def _with_seeders(self: _ApplicationABC) -> _ApplicationABC:
from cpl.database.service.seeder_service import SeederService
from cpl.application.host import Host
seeder_service: SeederService = self._services.get_service(SeederService)
Host.run(seeder_service.seed)
return self
def _add(collection: _ServiceCollection, db_context: Type, default_port: int, server_type: str): def _add(collection: _ServiceCollection, db_context: Type, default_port: int, server_type: str):
from cpl.core.console import Console from cpl.core.console import Console
from cpl.core.configuration import Configuration from cpl.core.configuration import Configuration
@@ -42,6 +62,7 @@ def add_postgres(collection: _ServiceCollection):
_add(collection, DBContext, 5432, ServerTypes.POSTGRES.value) _add(collection, DBContext, 5432, ServerTypes.POSTGRES.value)
_ServiceCollection.with_module(add_mysql, _mysql.__name__) _ServiceCollection.with_module(add_mysql, _mysql.__name__)
_ServiceCollection.with_module(add_postgres, _postgres.__name__) _ServiceCollection.with_module(add_postgres, _postgres.__name__)
_ApplicationABC.extend(_ApplicationABC.with_migrations, _with_migrations)
_ApplicationABC.extend(_ApplicationABC.with_seeders, _with_seeders)

View File

@@ -9,18 +9,15 @@ class ConnectionABC(ABC):
r"""ABC for the :class:`cpl.database.connection.database_connection.DatabaseConnection`""" r"""ABC for the :class:`cpl.database.connection.database_connection.DatabaseConnection`"""
@abstractmethod @abstractmethod
def __init__(self): def __init__(self): ...
pass
@property @property
@abstractmethod @abstractmethod
def server(self) -> MySQLConnectionAbstract: def server(self) -> MySQLConnectionAbstract: ...
pass
@property @property
@abstractmethod @abstractmethod
def cursor(self) -> MySQLCursorBuffered: def cursor(self) -> MySQLCursorBuffered: ...
pass
@abstractmethod @abstractmethod
def connect(self, database_settings: DatabaseSettings): def connect(self, database_settings: DatabaseSettings):

View File

@@ -4,5 +4,4 @@ from abc import ABC, abstractmethod
class DataSeederABC(ABC): class DataSeederABC(ABC):
@abstractmethod @abstractmethod
async def seed(self): async def seed(self): ...
pass

View File

@@ -4,8 +4,7 @@ from abc import ABC, abstractmethod
class ScopeABC(ABC): class ScopeABC(ABC):
r"""ABC for the class :class:`cpl.dependency.scope.Scope`""" r"""ABC for the class :class:`cpl.dependency.scope.Scope`"""
def __init__(self): def __init__(self): ...
pass
@property @property
@abstractmethod @abstractmethod

View File

@@ -1,8 +1,7 @@
from typing import Union, Type, Callable, Optional from typing import Union, Type, Callable
from cpl.core.log.logger import Logger from cpl.core.log.logger import Logger
from cpl.core.log.logger_abc import LoggerABC 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.core.typing import T, Service
from cpl.dependency.service_descriptor import ServiceDescriptor from cpl.dependency.service_descriptor import ServiceDescriptor
from cpl.dependency.service_lifetime_enum import ServiceLifetimeEnum from cpl.dependency.service_lifetime_enum import ServiceLifetimeEnum
@@ -46,29 +45,6 @@ class ServiceCollection:
return self return self
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)
return self
def add_pipes(self):
for pipe in PipeABC.__subclasses__():
self.add_transient(PipeABC, pipe)
return self
def add_singleton(self, service_type: T, service: Service = None): def add_singleton(self, service_type: T, service: Service = None):
self._add_descriptor_by_lifetime(service_type, ServiceLifetimeEnum.singleton, service) self._add_descriptor_by_lifetime(service_type, ServiceLifetimeEnum.singleton, service)
return self return self
@@ -81,7 +57,20 @@ class ServiceCollection:
self._add_descriptor_by_lifetime(service_type, ServiceLifetimeEnum.transient, service) self._add_descriptor_by_lifetime(service_type, ServiceLifetimeEnum.transient, service)
return self return self
def build_service_provider(self) -> ServiceProviderABC: def build(self) -> ServiceProviderABC:
sp = ServiceProvider(self._service_descriptors) sp = ServiceProvider(self._service_descriptors)
ServiceProviderABC.set_global_provider(sp) ServiceProviderABC.set_global_provider(sp)
return sp return sp
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_logging(self):
self.add_transient(LoggerABC, Logger)
return self

View File

@@ -136,7 +136,7 @@ class ServiceProvider(ServiceProviderABC):
else: else:
descriptors.append(copy.deepcopy(descriptor)) descriptors.append(copy.deepcopy(descriptor))
sb = ScopeBuilder(ServiceProvider(descriptors, self._database_context)) sb = ScopeBuilder(ServiceProvider(descriptors))
return sb.build() return sb.build()
def get_service(self, service_type: T, *args, **kwargs) -> Optional[R]: def get_service(self, service_type: T, *args, **kwargs) -> Optional[R]:

View File

@@ -1,7 +1,7 @@
import functools import functools
from abc import abstractmethod, ABC from abc import abstractmethod, ABC
from inspect import Signature, signature from inspect import Signature, signature
from typing import Optional from typing import Optional, Type
from cpl.core.typing import T, R from cpl.core.typing import T, R
from cpl.dependency.scope_abc import ScopeABC from cpl.dependency.scope_abc import ScopeABC
@@ -13,8 +13,7 @@ class ServiceProviderABC(ABC):
_provider: Optional["ServiceProviderABC"] = None _provider: Optional["ServiceProviderABC"] = None
@abstractmethod @abstractmethod
def __init__(self): def __init__(self): ...
pass
@classmethod @classmethod
def set_global_provider(cls, provider: "ServiceProviderABC"): def set_global_provider(cls, provider: "ServiceProviderABC"):
@@ -37,8 +36,7 @@ class ServiceProviderABC(ABC):
return cls._provider.get_services(instance_type, *args, **kwargs) return cls._provider.get_services(instance_type, *args, **kwargs)
@abstractmethod @abstractmethod
def _build_by_signature(self, sig: Signature, origin_service_type: type) -> list[R]: def _build_by_signature(self, sig: Signature, origin_service_type: type) -> list[R]: ...
pass
@abstractmethod @abstractmethod
def _build_service(self, service_type: type, *args, **kwargs) -> object: def _build_service(self, service_type: type, *args, **kwargs) -> object:
@@ -74,7 +72,7 @@ class ServiceProviderABC(ABC):
""" """
@abstractmethod @abstractmethod
def get_service(self, instance_type: T, *args, **kwargs) -> Optional[R]: def get_service(self, instance_type: Type[T], *args, **kwargs) -> Optional[T]:
r"""Returns instance of given type r"""Returns instance of given type
Parameter Parameter
@@ -88,7 +86,7 @@ class ServiceProviderABC(ABC):
""" """
@abstractmethod @abstractmethod
def get_services(self, service_type: T, *args, **kwargs) -> list[Optional[R]]: def get_services(self, service_type: Type[T], *args, **kwargs) -> list[Optional[T]]:
r"""Returns instance of given type r"""Returns instance of given type
Parameter Parameter

View File

@@ -5,25 +5,19 @@ from cpl.translation.translation_settings import TranslationSettings
class TranslationServiceABC(ABC): class TranslationServiceABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self): ...
pass
@abstractmethod @abstractmethod
def set_default_lang(self, lang: str): def set_default_lang(self, lang: str): ...
pass
@abstractmethod @abstractmethod
def set_lang(self, lang: str): def set_lang(self, lang: str): ...
pass
@abstractmethod @abstractmethod
def load(self, lang: str): def load(self, lang: str): ...
pass
@abstractmethod @abstractmethod
def load_by_settings(self, settings: TranslationSettings): def load_by_settings(self, settings: TranslationSettings): ...
pass
@abstractmethod @abstractmethod
def translate(self, key: str) -> str: def translate(self, key: str) -> str: ...
pass

View File

@@ -1,15 +0,0 @@
{
"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,9 +0,0 @@
{
"WorkspaceSettings": {
"DefaultProject": "async",
"Projects": {
"async": "src/async/async.json"
},
"Scripts": {}
}
}

View File

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

View File

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

View File

@@ -1,17 +0,0 @@
import asyncio
from cpl.application import ApplicationBuilder
from application import Application
from startup import Startup
async def main():
app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup)
app = await app_builder.build_async()
await app.run_async()
if __name__ == "__main__":
loop = asyncio.new_event_loop()
loop.run_until_complete(main())

View File

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

View File

@@ -15,32 +15,27 @@ def test_console():
Console.write_line("Hello World") Console.write_line("Hello World")
Console.write("\nName: ") Console.write("\nName: ")
Console.write_line(" Hello", Console.read_line()) Console.write_line(" Hello", Console.read_line())
Console.clear()
Console.write_at(5, 5, "at 5, 5") Console.write_at(5, 5, "at 5, 5")
Console.write_at(10, 10, "at 10, 10") 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.clear()
Console.spinner( Console.spinner(
"Test:", test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, text_foreground_color="green" "Test:", test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, text_foreground_color="green"
) )
test_console()
Console.write_line("HOLD BACK") Console.write_line("HOLD BACK")
# opts = [ opts = ["Option 1", "Option 2", "Option 3", "Option 4"]
# 'Option 1', selected = Console.select(
# 'Option 2', ">",
# 'Option 3', "Select item:",
# 'Option 4' opts,
# ] header_foreground_color=ForegroundColorEnum.blue,
# selected = Console.select( option_foreground_color=ForegroundColorEnum.green,
# '>', cursor_foreground_color=ForegroundColorEnum.red,
# 'Select item:', )
# opts, Console.write_line(f"You selected: {selected}")
# header_foreground_color=ForegroundColorEnum.blue,
# option_foreground_color=ForegroundColorEnum.green, Console.write_line()
# cursor_foreground_color=ForegroundColorEnum.red
# )
# Console.write_line(f'You selected: {selected}')
# # test_console()
#
# Console.write_line()

View File

@@ -1,7 +1,5 @@
from typing import Optional from cpl.application.abc.application_abc import ApplicationABC
from cpl.auth.keycloak import KeycloakAdmin
from cpl.application import ApplicationABC
from cpl.auth import KeycloakAdmin
from cpl.core.console import Console from cpl.core.console import Console
from cpl.core.environment import Environment from cpl.core.environment import Environment
from cpl.core.log import LoggerABC from cpl.core.log import LoggerABC
@@ -16,7 +14,7 @@ class Application(ApplicationABC):
def __init__(self, services: ServiceProviderABC): def __init__(self, services: ServiceProviderABC):
ApplicationABC.__init__(self, services) ApplicationABC.__init__(self, services)
self._logger: Optional[LoggerABC] = None self._logger: LoggerABC = services.get_service(LoggerABC)
async def test_daos(self): async def test_daos(self):
userDao: UserDao = self._services.get_service(UserDao) userDao: UserDao = self._services.get_service(UserDao)
@@ -30,9 +28,6 @@ class Application(ApplicationABC):
Console.write_line(await userDao.get_all()) Console.write_line(await userDao.get_all())
async def configure(self):
self._logger = self._services.get_service(LoggerABC)
async def main(self): async def main(self):
self._logger.debug(f"Host: {Environment.get_host_name()}") self._logger.debug(f"Host: {Environment.get_host_name()}")
self._logger.debug(f"Environment: {Environment.get_environment()}") self._logger.debug(f"Environment: {Environment.get_environment()}")

View File

@@ -1,17 +1,18 @@
from application import Application from application import Application
from cpl.application import ApplicationBuilder from cpl.application import ApplicationBuilder
from custom_permissions import CustomPermissions
from startup import Startup from startup import Startup
async def main(): def main():
app_builder = ApplicationBuilder(Application) builder = ApplicationBuilder(Application).with_startup(Startup)
app_builder.use_startup(Startup) app = builder.build()
app = await app_builder.build_async()
await app.run_async() app.with_permissions(CustomPermissions)
app.with_migrations("./scripts")
app.with_seeders()
app.run()
if __name__ == "__main__": if __name__ == "__main__":
import asyncio main()
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

View File

@@ -0,0 +1,23 @@
from application import Application
from cpl.application import ApplicationBuilder
from cpl.auth.permission.permissions_registry import PermissionsRegistry
from cpl.core.console import Console
from custom_permissions import CustomPermissions
from startup import Startup
def main():
builder = ApplicationBuilder(Application).with_startup(Startup)
app = builder.build()
app.with_permissions(CustomPermissions)
app.with_migrations("./scripts")
app.with_seeders()
Console.write_line(CustomPermissions.test.value in PermissionsRegistry.get())
app.run()
Console.write_line("Hello from main_simplified.py!")
if __name__ == "__main__":
main()

View File

@@ -1,30 +1,26 @@
from cpl import auth from cpl import auth
from cpl.application.async_startup_abc import AsyncStartupABC from cpl.application.abc.startup_abc import StartupABC
from cpl.auth import permission from cpl.auth import permission
from cpl.auth.permission.permissions_registry import PermissionsRegistry
from cpl.core.configuration import Configuration from cpl.core.configuration import Configuration
from cpl.core.environment import Environment from cpl.core.environment import Environment
from cpl.core.log import Logger, LoggerABC from cpl.core.log import Logger, LoggerABC
from cpl.database import mysql from cpl.database import mysql
from cpl.database.abc.data_access_object_abc import DataAccessObjectABC from cpl.database.abc.data_access_object_abc import DataAccessObjectABC
from cpl.database.service.migration_service import MigrationService
from cpl.database.service.seeder_service import SeederService
from cpl.dependency import ServiceCollection from cpl.dependency import ServiceCollection
from custom_permissions import CustomPermissions
from model.city_dao import CityDao from model.city_dao import CityDao
from model.user_dao import UserDao from model.user_dao import UserDao
class Startup(AsyncStartupABC): class Startup(StartupABC):
def __init__(self):
AsyncStartupABC.__init__(self)
async def configure_configuration(self, configuration: Configuration, environment: Environment): @staticmethod
configuration.add_json_file(f"appsettings.json") async def configure_configuration():
configuration.add_json_file(f"appsettings.{environment.get_environment()}.json") Configuration.add_json_file(f"appsettings.json")
configuration.add_json_file(f"appsettings.{environment.get_host_name()}.json", optional=True) Configuration.add_json_file(f"appsettings.{Environment.get_environment()}.json")
Configuration.add_json_file(f"appsettings.{Environment.get_host_name()}.json", optional=True)
async def configure_services(self, services: ServiceCollection, environment: Environment): @staticmethod
async def configure_services(services: ServiceCollection):
services.add_module(mysql) services.add_module(mysql)
services.add_module(auth) services.add_module(auth)
services.add_module(permission) services.add_module(permission)
@@ -33,13 +29,3 @@ class Startup(AsyncStartupABC):
services.add_transient(DataAccessObjectABC, CityDao) services.add_transient(DataAccessObjectABC, CityDao)
services.add_singleton(LoggerABC, Logger) services.add_singleton(LoggerABC, Logger)
PermissionsRegistry.with_enum(CustomPermissions)
provider = services.build_service_provider()
migration_service: MigrationService = provider.get_service(MigrationService)
migration_service.with_directory("./scripts")
await migration_service.migrate()
seeder_service: SeederService = provider.get_service(SeederService)
await seeder_service.seed()

View File

@@ -1,5 +1,4 @@
from cpl.application import ApplicationABC from cpl.application.abc import ApplicationABC
from cpl.core.configuration import ConfigurationABC
from cpl.core.console.console import Console from cpl.core.console.console import Console
from cpl.dependency import ServiceProviderABC from cpl.dependency import ServiceProviderABC
from cpl.dependency.scope import Scope from cpl.dependency.scope import Scope
@@ -11,15 +10,14 @@ from di.tester import Tester
class Application(ApplicationABC): class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): def __init__(self, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services) ApplicationABC.__init__(self, services)
def _part_of_scoped(self): def _part_of_scoped(self):
ts: TestService = self._services.get_service(TestService) ts: TestService = self._services.get_service(TestService)
ts.run() ts.run()
def configure(self): def configure(self): ...
pass
def main(self): def main(self):
with self._services.create_scope() as scope: with self._services.create_scope() as scope:

View File

@@ -6,7 +6,7 @@ from di.startup import Startup
def main(): def main():
app_builder = ApplicationBuilder(Application) app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup) app_builder.with_startup(Startup)
app_builder.build().run() app_builder.build().run()

View File

@@ -1,12 +1,10 @@
from cpl.application import StartupABC from cpl.application.abc import StartupABC
from cpl.core.configuration import ConfigurationABC
from cpl.dependency import ServiceProviderABC, ServiceCollection from cpl.dependency import ServiceProviderABC, ServiceCollection
from cpl.core.environment import Environment from di.di_tester_service import DITesterService
from di.test1_service import Test1Service from di.test1_service import Test1Service
from di.test2_service import Test2Service from di.test2_service import Test2Service
from di.test_abc import TestABC from di.test_abc import TestABC
from di.test_service import TestService from di.test_service import TestService
from di.di_tester_service import DITesterService
from di.tester import Tester from di.tester import Tester
@@ -14,10 +12,9 @@ class Startup(StartupABC):
def __init__(self): def __init__(self):
StartupABC.__init__(self) StartupABC.__init__(self)
def configure_configuration(self, configuration: ConfigurationABC, environment: Environment) -> ConfigurationABC: def configure_configuration(self): ...
return configuration
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC: def configure_services(self, services: ServiceCollection) -> ServiceProviderABC:
services.add_scoped(TestService) services.add_scoped(TestService)
services.add_scoped(DITesterService) services.add_scoped(DITesterService)
@@ -25,4 +22,4 @@ class Startup(StartupABC):
services.add_singleton(TestABC, Test2Service) services.add_singleton(TestABC, Test2Service)
services.add_singleton(Tester) services.add_singleton(Tester)
return services.build_service_provider() return services.build()

View File

@@ -1,4 +1,3 @@
from cpl.core.configuration import ConfigurationABC
from cpl.dependency import ServiceProvider, ServiceProviderABC from cpl.dependency import ServiceProvider, ServiceProviderABC
from di.test_service import TestService from di.test_service import TestService
@@ -6,5 +5,5 @@ from di.test_service import TestService
class StaticTest: class StaticTest:
@staticmethod @staticmethod
@ServiceProvider.inject @ServiceProvider.inject
def test(services: ServiceProviderABC, config: ConfigurationABC, t1: TestService): def test(services: ServiceProviderABC, t1: TestService):
t1.run() t1.run()

View File

@@ -6,7 +6,7 @@ from cpl.core.utils.string import String
class TestService: class TestService:
def __init__(self): def __init__(self):
self._name = String.random_string(string.ascii_lowercase, 8) self._name = String.random(8)
def run(self): def run(self):
Console.write_line(f"Im {self._name}") Console.write_line(f"Im {self._name}")

View File

@@ -1,7 +1,7 @@
import time import time
from typing import Optional from typing import Optional
from cpl.application.application_abc import ApplicationABC from cpl.application.abc import ApplicationABC
from cpl.core.configuration import Configuration from cpl.core.configuration import Configuration
from cpl.core.console import Console from cpl.core.console import Console
from cpl.dependency import ServiceProviderABC from cpl.dependency import ServiceProviderABC
@@ -18,8 +18,8 @@ class Application(ApplicationABC):
def __init__(self, services: ServiceProviderABC): def __init__(self, services: ServiceProviderABC):
ApplicationABC.__init__(self, services) ApplicationABC.__init__(self, services)
self._logger: Optional[LoggerABC] = None self._logger = self._services.get_service(LoggerABC)
self._mailer: Optional[EMailClientABC] = None self._mailer = self._services.get_service(EMailClientABC)
def test_send_mail(self): def test_send_mail(self):
mail = EMail() mail = EMail()
@@ -35,10 +35,6 @@ class Application(ApplicationABC):
def _wait(time_ms: int): def _wait(time_ms: int):
time.sleep(time_ms) time.sleep(time_ms)
def configure(self):
self._logger = self._services.get_service(LoggerABC)
self._mailer = self._services.get_service(EMailClientABC)
def main(self): def main(self):
self._logger.debug(f"Host: {Environment.get_host_name()}") self._logger.debug(f"Host: {Environment.get_host_name()}")
self._logger.debug(f"Environment: {Environment.get_environment()}") self._logger.debug(f"Environment: {Environment.get_environment()}")

View File

@@ -7,9 +7,9 @@ from test_startup_extension import TestStartupExtension
def main(): def main():
app_builder = ApplicationBuilder(Application) app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup) app_builder.with_startup(Startup)
app_builder.use_extension(TestStartupExtension) app_builder.with_extension(TestStartupExtension)
app_builder.use_extension(TestExtension) app_builder.with_extension(TestExtension)
app_builder.build().run() app_builder.build().run()

View File

@@ -1,22 +1,22 @@
from cpl import mail from cpl import mail
from cpl.application import StartupABC from cpl.application.abc import StartupABC
from cpl.core.configuration import Configuration from cpl.core.configuration import Configuration
from cpl.dependency import ServiceCollection, ServiceProviderABC
from cpl.core.environment import Environment from cpl.core.environment import Environment
from cpl.core.pipes import IPAddressPipe from cpl.core.pipes import IPAddressPipe
from cpl.dependency import ServiceCollection
from test_service import TestService from test_service import TestService
class Startup(StartupABC): class Startup(StartupABC):
def __init__(self):
StartupABC.__init__(self)
def configure_configuration(self, config: Configuration, env: Environment): @staticmethod
config.add_json_file(f"appsettings.json") def configure_configuration():
config.add_json_file(f"appsettings.{env.get_environment()}.json") Configuration.add_json_file(f"appsettings.json")
config.add_json_file(f"appsettings.{env.get_host_name()}.json", optional=True) Configuration.add_json_file(f"appsettings.{Environment.get_environment()}.json")
Configuration.add_json_file(f"appsettings.{Environment.get_host_name()}.json", optional=True)
def configure_services(self, services: ServiceCollection, env: Environment): @staticmethod
def configure_services(services: ServiceCollection):
services.add_logging() services.add_logging()
services.add_module(mail) services.add_module(mail)
services.add_transient(IPAddressPipe) services.add_transient(IPAddressPipe)

View File

@@ -1,12 +1,10 @@
from cpl.application import ApplicationExtensionABC from cpl.application.abc import ApplicationExtensionABC
from cpl.core.configuration import Configuration
from cpl.core.console import Console from cpl.core.console import Console
from cpl.dependency import ServiceProviderABC from cpl.dependency import ServiceProviderABC
class TestExtension(ApplicationExtensionABC): class TestExtension(ApplicationExtensionABC):
def __init__(self):
ApplicationExtensionABC.__init__(self)
def run(self, config: Configuration, services: ServiceProviderABC): @staticmethod
def run(services: ServiceProviderABC):
Console.write_line("Hello World from App Extension") Console.write_line("Hello World from App Extension")

View File

@@ -1,16 +1,14 @@
from cpl.application import StartupExtensionABC from cpl.application.abc import StartupExtensionABC
from cpl.core.configuration import Configuration
from cpl.core.console import Console from cpl.core.console import Console
from cpl.dependency import ServiceCollection from cpl.dependency import ServiceCollection
from cpl.core.environment import Environment
class TestStartupExtension(StartupExtensionABC): class TestStartupExtension(StartupExtensionABC):
def __init__(self):
StartupExtensionABC.__init__(self)
def configure_configuration(self, config: Configuration, env: Environment): @staticmethod
def configure_configuration():
Console.write_line("config") Console.write_line("config")
def configure_services(self, services: ServiceCollection, env: Environment): @staticmethod
def configure_services(services: ServiceCollection):
Console.write_line("services") Console.write_line("services")

View File

@@ -18,8 +18,7 @@ class Application(ApplicationABC):
self._translation.load_by_settings(config.get_configuration(TranslationSettings)) self._translation.load_by_settings(config.get_configuration(TranslationSettings))
self._translation.set_default_lang("de") self._translation.set_default_lang("de")
def configure(self): def configure(self): ...
pass
def main(self): def main(self):
Console.write_line(self._translate.transform("main.text.hello_world")) Console.write_line(self._translate.transform("main.text.hello_world"))

View File

@@ -6,7 +6,7 @@ from translation.startup import Startup
def main(): def main():
app_builder = ApplicationBuilder(Application) app_builder = ApplicationBuilder(Application)
app_builder.use_startup(Startup) app_builder.with_startup(Startup)
app_builder.build().run() app_builder.build().run()

View File

@@ -14,4 +14,4 @@ class Startup(StartupABC):
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC: def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
services.add_translation() services.add_translation()
return services.build_service_provider() return services.build()

View File

@@ -13,8 +13,7 @@ class Application(ApplicationABC):
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC): def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
ApplicationABC.__init__(self, config, services) ApplicationABC.__init__(self, config, services)
def configure(self): def configure(self): ...
pass
def main(self): def main(self):
runner = unittest.TextTestRunner() runner = unittest.TextTestRunner()

View File

@@ -2,8 +2,6 @@ from unittests_cli.abc.command_test_case import CommandTestCase
class CustomTestCase(CommandTestCase): class CustomTestCase(CommandTestCase):
def setUp(self): def setUp(self): ...
pass
def test_equal(self): def test_equal(self): ...
pass

View File

@@ -26,8 +26,7 @@ class VersionTestCase(CommandTestCase):
self._block_packages = "" self._block_packages = ""
self._name = "CPL CLI" self._name = "CPL CLI"
def setUp(self): def setUp(self): ...
pass
def _get_version_output(self, version: str): def _get_version_output(self, version: str):
index = 0 index = 0

View File

@@ -61,7 +61,7 @@ class ConfigurationTestCase(unittest.TestCase):
self._config.create_console_argument(ArgumentTypeEnum.Variable, "", "var", [], "=") self._config.create_console_argument(ArgumentTypeEnum.Variable, "", "var", [], "=")
self.assertIsNone(self._config.get_configuration("var")) self.assertIsNone(self._config.get_configuration("var"))
self._config.parse_console_arguments(sc.build_service_provider()) self._config.parse_console_arguments(sc.build())
mocked_exec.run.assert_called() mocked_exec.run.assert_called()
self.assertEqual("test", self._config.get_configuration("var")) self.assertEqual("test", self._config.get_configuration("var"))

View File

@@ -31,28 +31,28 @@ class ConsoleArgumentsTestCase(unittest.TestCase):
def test_flag(self): def test_flag(self):
sys.argv.append("flag") sys.argv.append("flag")
self._config.parse_console_arguments(self._sc.build_service_provider()) self._config.parse_console_arguments(self._sc.build())
self.assertIn("flag", self._config.additional_arguments) self.assertIn("flag", self._config.additional_arguments)
def test_var(self): def test_var(self):
sys.argv.append("var=1") sys.argv.append("var=1")
sys.argv.append("var2=1") sys.argv.append("var2=1")
self._config.parse_console_arguments(self._sc.build_service_provider()) self._config.parse_console_arguments(self._sc.build())
self.assertEqual("1", self._config.get_configuration("var")) self.assertEqual("1", self._config.get_configuration("var"))
self.assertIsNone(self._config.get_configuration("var1")) self.assertIsNone(self._config.get_configuration("var1"))
def test_exec(self): def test_exec(self):
sys.argv.append("exec") sys.argv.append("exec")
self._config.parse_console_arguments(self._sc.build_service_provider()) self._config.parse_console_arguments(self._sc.build())
self._mocked_exec.run.assert_called() self._mocked_exec.run.assert_called()
def test_exec_with_one_flag(self): def test_exec_with_one_flag(self):
sys.argv.append("exec") sys.argv.append("exec")
sys.argv.append("--dev") sys.argv.append("--dev")
self._config.parse_console_arguments(self._sc.build_service_provider()) self._config.parse_console_arguments(self._sc.build())
self._mocked_exec.run.assert_called() self._mocked_exec.run.assert_called()
self.assertIn("dev", self._config.additional_arguments) self.assertIn("dev", self._config.additional_arguments)
@@ -60,7 +60,7 @@ class ConsoleArgumentsTestCase(unittest.TestCase):
sys.argv.append("exec") sys.argv.append("exec")
sys.argv.append("--d") sys.argv.append("--d")
self._config.parse_console_arguments(self._sc.build_service_provider()) self._config.parse_console_arguments(self._sc.build())
self._mocked_exec.run.assert_called() self._mocked_exec.run.assert_called()
self.assertIn("dev", self._config.additional_arguments) self.assertIn("dev", self._config.additional_arguments)
@@ -69,7 +69,7 @@ class ConsoleArgumentsTestCase(unittest.TestCase):
sys.argv.append("--dev") sys.argv.append("--dev")
sys.argv.append("--virtual") sys.argv.append("--virtual")
self._config.parse_console_arguments(self._sc.build_service_provider()) self._config.parse_console_arguments(self._sc.build())
self._mocked_exec.run.assert_called() self._mocked_exec.run.assert_called()
self.assertIn("dev", self._config.additional_arguments) self.assertIn("dev", self._config.additional_arguments)
self.assertIn("virtual", self._config.additional_arguments) self.assertIn("virtual", self._config.additional_arguments)

View File

@@ -50,7 +50,7 @@ class ServiceCollectionTestCase(unittest.TestCase):
self._sc.add_singleton(Mock) self._sc.add_singleton(Mock)
service = self._sc._service_descriptors[0] service = self._sc._service_descriptors[0]
self.assertIsNone(service.implementation) self.assertIsNone(service.implementation)
sp = self._sc.build_service_provider() sp = self._sc.build()
self.assertTrue(isinstance(sp, ServiceProviderABC)) self.assertTrue(isinstance(sp, ServiceProviderABC))
self.assertTrue(isinstance(sp.get_service(Mock), Mock)) self.assertTrue(isinstance(sp.get_service(Mock), Mock))
self.assertIsNotNone(service.implementation) self.assertIsNotNone(service.implementation)

View File

@@ -39,7 +39,7 @@ class ServiceProviderTestCase(unittest.TestCase):
.add_singleton(TestService) .add_singleton(TestService)
.add_transient(DifferentService) .add_transient(DifferentService)
.add_scoped(MoreDifferentService) .add_scoped(MoreDifferentService)
.build_service_provider() .build()
) )
count = self._services.get_service(ServiceCount) count = self._services.get_service(ServiceCount)

View File

@@ -4,8 +4,7 @@ from cpl.core.pipes import BoolPipe
class BoolPipeTestCase(unittest.TestCase): class BoolPipeTestCase(unittest.TestCase):
def setUp(self): def setUp(self): ...
pass
def test_transform(self): def test_transform(self):
self.assertEqual("true", BoolPipe.to_str(True)) self.assertEqual("true", BoolPipe.to_str(True))

View File

@@ -4,8 +4,7 @@ from cpl.core.pipes import IPAddressPipe
class IPAddressTestCase(unittest.TestCase): class IPAddressTestCase(unittest.TestCase):
def setUp(self): def setUp(self): ...
pass
def test_transform(self): def test_transform(self):
self.assertEqual("192.168.178.1", IPAddressPipe.to_str([192, 168, 178, 1])) self.assertEqual("192.168.178.1", IPAddressPipe.to_str([192, 168, 178, 1]))

View File

@@ -4,8 +4,7 @@ from cpl.core.utils import CredentialManager
class CredentialManagerTestCase(unittest.TestCase): class CredentialManagerTestCase(unittest.TestCase):
def setUp(self): def setUp(self): ...
pass
def test_encrypt(self): def test_encrypt(self):
self.assertEqual("ZkVjSkplQUx4aW1zWHlPbA==", CredentialManager.encrypt("fEcJJeALximsXyOl")) self.assertEqual("ZkVjSkplQUx4aW1zWHlPbA==", CredentialManager.encrypt("fEcJJeALximsXyOl"))

View File

@@ -18,8 +18,7 @@ class TestClass:
class JSONProcessorTestCase(unittest.TestCase): class JSONProcessorTestCase(unittest.TestCase):
def setUp(self): def setUp(self): ...
pass
def test_process(self): def test_process(self):
test_dict = { test_dict = {

View File

@@ -5,8 +5,7 @@ from cpl.core.utils import String
class StringTestCase(unittest.TestCase): class StringTestCase(unittest.TestCase):
def setUp(self): def setUp(self): ...
pass
def test_convert_to_camel_case(self): def test_convert_to_camel_case(self):
expected = "HelloWorld" expected = "HelloWorld"

View File

@@ -20,8 +20,7 @@ class TranslationTestCase(unittest.TestCase):
self._translation.set_default_lang("de") self._translation.set_default_lang("de")
self._translate = TranslatePipe(self._translation) self._translate = TranslatePipe(self._translation)
def cleanUp(self): def cleanUp(self): ...
pass
def test_service(self): def test_service(self):
self.assertEqual("Hallo Welt", self._translation.translate("main.text.hello_world")) self.assertEqual("Hallo Welt", self._translation.translate("main.text.hello_world"))