Compare commits
5 Commits
2025.09.17
...
2025.09.17
| Author | SHA1 | Date | |
|---|---|---|---|
| dfdc31512d | |||
| ab7ff7da93 | |||
| 41087a838b | |||
| 836b92ccbf | |||
| 8aaba22940 |
@@ -1,6 +1 @@
|
||||
from .application_abc import ApplicationABC
|
||||
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
|
||||
|
||||
4
src/cpl-application/cpl/application/abc/__init__.py
Normal file
4
src/cpl-application/cpl/application/abc/__init__.py
Normal 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
|
||||
73
src/cpl-application/cpl/application/abc/application_abc.py
Normal file
73
src/cpl-application/cpl/application/abc/application_abc.py
Normal 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): ...
|
||||
@@ -0,0 +1,10 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from cpl.dependency import ServiceProviderABC
|
||||
|
||||
|
||||
class ApplicationExtensionABC(ABC):
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def run(services: ServiceProviderABC): ...
|
||||
@@ -3,19 +3,17 @@ from abc import ABC, abstractmethod
|
||||
from cpl.dependency.service_collection import ServiceCollection
|
||||
|
||||
|
||||
class AsyncStartupABC(ABC):
|
||||
class StartupABC(ABC):
|
||||
r"""ABC for the startup class"""
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
async def configure_configuration(self):
|
||||
def configure_configuration():
|
||||
r"""Creates configuration of application"""
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
async def configure_services(self, service: ServiceCollection):
|
||||
def configure_services(service: ServiceCollection):
|
||||
r"""Creates service provider
|
||||
|
||||
Parameter:
|
||||
@@ -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`
|
||||
"""
|
||||
@@ -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`
|
||||
"""
|
||||
@@ -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.application_builder_abc import ApplicationBuilderABC
|
||||
from cpl.application.application_extension_abc import ApplicationExtensionABC
|
||||
from cpl.application.async_application_extension_abc import AsyncApplicationExtensionABC
|
||||
from cpl.application.async_startup_abc import AsyncStartupABC
|
||||
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.application.abc.application_abc import ApplicationABC
|
||||
from cpl.application.abc.application_extension_abc import ApplicationExtensionABC
|
||||
from cpl.application.abc.startup_abc import StartupABC
|
||||
from cpl.application.abc.startup_extension_abc import StartupExtensionABC
|
||||
from cpl.application.host import Host
|
||||
from cpl.dependency.service_collection import ServiceCollection
|
||||
from cpl.core.environment import Environment
|
||||
|
||||
|
||||
class ApplicationBuilder(ApplicationBuilderABC):
|
||||
r"""This is class is used to build an object of :class:`cpl.application.application_abc.ApplicationABC`
|
||||
|
||||
Parameter:
|
||||
app: Type[:class:`cpl.application.application_abc.ApplicationABC`]
|
||||
Application to build
|
||||
"""
|
||||
class ApplicationBuilder:
|
||||
r"""A builder for constructing an application with configurable services and extensions."""
|
||||
|
||||
def __init__(self, app: Type[ApplicationABC]):
|
||||
ApplicationBuilderABC.__init__(self)
|
||||
self._app = app
|
||||
self._startup: Optional[StartupABC | AsyncStartupABC] = None
|
||||
assert app is not None, "app must not be None"
|
||||
assert issubclass(app, ApplicationABC), "app must be an subclass of ApplicationABC or its subclass"
|
||||
|
||||
self._app = app if app is not None else ApplicationABC
|
||||
|
||||
self._services = ServiceCollection()
|
||||
|
||||
self._app_extensions: list[Type[ApplicationExtensionABC | AsyncApplicationExtensionABC]] = []
|
||||
self._startup_extensions: list[Type[StartupExtensionABC | AsyncStartupABC]] = []
|
||||
self._startup: Optional[StartupABC] = None
|
||||
self._app_extensions: list[Type[ApplicationExtensionABC]] = []
|
||||
self._startup_extensions: list[Type[StartupExtensionABC]] = []
|
||||
|
||||
def use_startup(self, startup: Type[StartupABC | AsyncStartupABC]) -> "ApplicationBuilder":
|
||||
self._startup = startup()
|
||||
self._async_loop = asyncio.get_event_loop()
|
||||
|
||||
@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
|
||||
|
||||
def use_extension(
|
||||
def with_extension(
|
||||
self,
|
||||
extension: Type[
|
||||
ApplicationExtensionABC | AsyncApplicationExtensionABC | StartupExtensionABC | AsyncStartupExtensionABC
|
||||
],
|
||||
extension: Type[ApplicationExtensionABC | StartupExtensionABC],
|
||||
) -> "ApplicationBuilder":
|
||||
if (
|
||||
issubclass(extension, ApplicationExtensionABC) or issubclass(extension, AsyncApplicationExtensionABC)
|
||||
) and extension not in self._app_extensions:
|
||||
if (issubclass(extension, ApplicationExtensionABC)) and extension not in self._app_extensions:
|
||||
self._app_extensions.append(extension)
|
||||
elif (
|
||||
issubclass(extension, StartupExtensionABC) or issubclass(extension, AsyncStartupExtensionABC)
|
||||
) and extension not in self._startup_extensions:
|
||||
elif (issubclass(extension, StartupExtensionABC)) and extension not in self._startup_extensions:
|
||||
self._startup_extensions.append(extension)
|
||||
|
||||
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:
|
||||
self._build_startup()
|
||||
for extension in self._startup_extensions:
|
||||
Host.run(extension.configure_configuration)
|
||||
Host.run(extension.configure_services, self._services)
|
||||
|
||||
config = Configuration
|
||||
services = self._services.build_service_provider()
|
||||
if self._startup is not None:
|
||||
Host.run(self._startup.configure_configuration)
|
||||
Host.run(self._startup.configure_services, self._services)
|
||||
|
||||
for ex in self._app_extensions:
|
||||
extension = ex()
|
||||
extension.run(config, services)
|
||||
for extension in self._app_extensions:
|
||||
Host.run(extension.run, self.service_provider)
|
||||
|
||||
return self._app(services)
|
||||
|
||||
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)
|
||||
return self._app(self.service_provider)
|
||||
|
||||
@@ -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`
|
||||
"""
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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`
|
||||
"""
|
||||
17
src/cpl-application/cpl/application/host.py
Normal file
17
src/cpl-application/cpl/application/host.py
Normal 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)
|
||||
@@ -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`
|
||||
"""
|
||||
@@ -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`
|
||||
"""
|
||||
@@ -1,13 +1,24 @@
|
||||
from cpl.auth import permission as _permission
|
||||
from cpl.auth.keycloak.keycloak_admin import KeycloakAdmin
|
||||
from cpl.auth.keycloak.keycloak_client import KeycloakClient
|
||||
from cpl.dependency import ServiceCollection as _ServiceCollection
|
||||
from enum import Enum
|
||||
from typing import Type
|
||||
|
||||
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 .keycloak_settings import KeycloakSettings
|
||||
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):
|
||||
from .schema._administration.auth_user_dao import AuthUserDao
|
||||
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
|
||||
|
||||
try:
|
||||
collection.add_singleton(KeycloakClient)
|
||||
collection.add_singleton(KeycloakAdmin)
|
||||
collection.add_singleton(_KeycloakClient)
|
||||
collection.add_singleton(_KeycloakAdmin)
|
||||
|
||||
_add_daos(collection)
|
||||
|
||||
provider = collection.build_service_provider()
|
||||
provider = collection.build()
|
||||
migration_service: MigrationService = provider.get_service(MigrationService)
|
||||
if ServerType.server_type == ServerTypes.POSTGRES:
|
||||
migration_service.with_directory(
|
||||
@@ -68,3 +79,4 @@ def add_permission(collection: _ServiceCollection):
|
||||
|
||||
_ServiceCollection.with_module(add_auth, __name__)
|
||||
_ServiceCollection.with_module(add_permission, _permission.__name__)
|
||||
_ApplicationABC.extend(_ApplicationABC.with_permissions, _with_permissions)
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import Optional
|
||||
from async_property import async_property
|
||||
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.permission.permissions import Permissions
|
||||
from cpl.core.typing import SerialId
|
||||
|
||||
@@ -2,4 +2,6 @@ from abc import ABC
|
||||
|
||||
|
||||
class ConfigurationModelABC(ABC):
|
||||
pass
|
||||
r"""
|
||||
ABC for configuration model classes
|
||||
"""
|
||||
|
||||
@@ -7,12 +7,10 @@ class LoggerABC(ABC):
|
||||
r"""ABC for :class:`cpl.core.log.logger_service.Logger`"""
|
||||
|
||||
@abstractmethod
|
||||
def set_level(self, level: str):
|
||||
pass
|
||||
def set_level(self, level: str): ...
|
||||
|
||||
@abstractmethod
|
||||
def _format_message(self, level: str, timestamp, *messages: Messages) -> str:
|
||||
pass
|
||||
def _format_message(self, level: str, timestamp, *messages: Messages) -> str: ...
|
||||
|
||||
@abstractmethod
|
||||
def header(self, string: str):
|
||||
|
||||
@@ -7,10 +7,8 @@ from cpl.core.typing import T
|
||||
class PipeABC(ABC, Generic[T]):
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def to_str(value: T, *args) -> str:
|
||||
pass
|
||||
def to_str(value: T, *args) -> str: ...
|
||||
|
||||
@staticmethod
|
||||
@abstractmethod
|
||||
def from_str(value: str, *args) -> T:
|
||||
pass
|
||||
def from_str(value: str, *args) -> T: ...
|
||||
|
||||
@@ -1,11 +1,31 @@
|
||||
from typing import Type
|
||||
|
||||
from cpl.application.abc import ApplicationABC as _ApplicationABC
|
||||
from cpl.dependency import ServiceCollection as _ServiceCollection
|
||||
from . import mysql as _mysql
|
||||
from . import postgres as _postgres
|
||||
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):
|
||||
from cpl.core.console import Console
|
||||
from cpl.core.configuration import Configuration
|
||||
@@ -42,6 +62,7 @@ def add_postgres(collection: _ServiceCollection):
|
||||
_add(collection, DBContext, 5432, ServerTypes.POSTGRES.value)
|
||||
|
||||
|
||||
|
||||
_ServiceCollection.with_module(add_mysql, _mysql.__name__)
|
||||
_ServiceCollection.with_module(add_postgres, _postgres.__name__)
|
||||
_ApplicationABC.extend(_ApplicationABC.with_migrations, _with_migrations)
|
||||
_ApplicationABC.extend(_ApplicationABC.with_seeders, _with_seeders)
|
||||
|
||||
@@ -9,18 +9,15 @@ class ConnectionABC(ABC):
|
||||
r"""ABC for the :class:`cpl.database.connection.database_connection.DatabaseConnection`"""
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(self): ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def server(self) -> MySQLConnectionAbstract:
|
||||
pass
|
||||
def server(self) -> MySQLConnectionAbstract: ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def cursor(self) -> MySQLCursorBuffered:
|
||||
pass
|
||||
def cursor(self) -> MySQLCursorBuffered: ...
|
||||
|
||||
@abstractmethod
|
||||
def connect(self, database_settings: DatabaseSettings):
|
||||
|
||||
@@ -4,5 +4,4 @@ from abc import ABC, abstractmethod
|
||||
class DataSeederABC(ABC):
|
||||
|
||||
@abstractmethod
|
||||
async def seed(self):
|
||||
pass
|
||||
async def seed(self): ...
|
||||
|
||||
@@ -4,8 +4,7 @@ from abc import ABC, abstractmethod
|
||||
class ScopeABC(ABC):
|
||||
r"""ABC for the class :class:`cpl.dependency.scope.Scope`"""
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(self): ...
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
|
||||
@@ -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_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
|
||||
@@ -46,29 +45,6 @@ class ServiceCollection:
|
||||
|
||||
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):
|
||||
self._add_descriptor_by_lifetime(service_type, ServiceLifetimeEnum.singleton, service)
|
||||
return self
|
||||
@@ -81,7 +57,20 @@ class ServiceCollection:
|
||||
self._add_descriptor_by_lifetime(service_type, ServiceLifetimeEnum.transient, service)
|
||||
return self
|
||||
|
||||
def build_service_provider(self) -> ServiceProviderABC:
|
||||
def build(self) -> ServiceProviderABC:
|
||||
sp = ServiceProvider(self._service_descriptors)
|
||||
ServiceProviderABC.set_global_provider(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
|
||||
|
||||
@@ -136,7 +136,7 @@ class ServiceProvider(ServiceProviderABC):
|
||||
else:
|
||||
descriptors.append(copy.deepcopy(descriptor))
|
||||
|
||||
sb = ScopeBuilder(ServiceProvider(descriptors, self._database_context))
|
||||
sb = ScopeBuilder(ServiceProvider(descriptors))
|
||||
return sb.build()
|
||||
|
||||
def get_service(self, service_type: T, *args, **kwargs) -> Optional[R]:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import functools
|
||||
from abc import abstractmethod, ABC
|
||||
from inspect import Signature, signature
|
||||
from typing import Optional
|
||||
from typing import Optional, Type
|
||||
|
||||
from cpl.core.typing import T, R
|
||||
from cpl.dependency.scope_abc import ScopeABC
|
||||
@@ -13,8 +13,7 @@ class ServiceProviderABC(ABC):
|
||||
_provider: Optional["ServiceProviderABC"] = None
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(self): ...
|
||||
|
||||
@classmethod
|
||||
def set_global_provider(cls, provider: "ServiceProviderABC"):
|
||||
@@ -37,8 +36,7 @@ class ServiceProviderABC(ABC):
|
||||
return cls._provider.get_services(instance_type, *args, **kwargs)
|
||||
|
||||
@abstractmethod
|
||||
def _build_by_signature(self, sig: Signature, origin_service_type: type) -> list[R]:
|
||||
pass
|
||||
def _build_by_signature(self, sig: Signature, origin_service_type: type) -> list[R]: ...
|
||||
|
||||
@abstractmethod
|
||||
def _build_service(self, service_type: type, *args, **kwargs) -> object:
|
||||
@@ -74,7 +72,7 @@ class ServiceProviderABC(ABC):
|
||||
"""
|
||||
|
||||
@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
|
||||
|
||||
Parameter
|
||||
@@ -88,7 +86,7 @@ class ServiceProviderABC(ABC):
|
||||
"""
|
||||
|
||||
@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
|
||||
|
||||
Parameter
|
||||
|
||||
@@ -5,25 +5,19 @@ from cpl.translation.translation_settings import TranslationSettings
|
||||
|
||||
class TranslationServiceABC(ABC):
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
pass
|
||||
def __init__(self): ...
|
||||
|
||||
@abstractmethod
|
||||
def set_default_lang(self, lang: str):
|
||||
pass
|
||||
def set_default_lang(self, lang: str): ...
|
||||
|
||||
@abstractmethod
|
||||
def set_lang(self, lang: str):
|
||||
pass
|
||||
def set_lang(self, lang: str): ...
|
||||
|
||||
@abstractmethod
|
||||
def load(self, lang: str):
|
||||
pass
|
||||
def load(self, lang: str): ...
|
||||
|
||||
@abstractmethod
|
||||
def load_by_settings(self, settings: TranslationSettings):
|
||||
pass
|
||||
def load_by_settings(self, settings: TranslationSettings): ...
|
||||
|
||||
@abstractmethod
|
||||
def translate(self, key: str) -> str:
|
||||
pass
|
||||
def translate(self, key: str) -> str: ...
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"WorkspaceSettings": {
|
||||
"DefaultProject": "async",
|
||||
"Projects": {
|
||||
"async": "src/async/async.json"
|
||||
},
|
||||
"Scripts": {}
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
@@ -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": []
|
||||
}
|
||||
}
|
||||
@@ -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())
|
||||
@@ -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()
|
||||
@@ -15,32 +15,27 @@ def test_console():
|
||||
Console.write_line("Hello World")
|
||||
Console.write("\nName: ")
|
||||
Console.write_line(" Hello", Console.read_line())
|
||||
Console.clear()
|
||||
Console.write_at(5, 5, "at 5, 5")
|
||||
Console.write_at(10, 10, "at 10, 10")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
Console.write_line("Hello World\n")
|
||||
Console.clear()
|
||||
Console.spinner(
|
||||
"Test:", test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, text_foreground_color="green"
|
||||
)
|
||||
test_console()
|
||||
Console.write_line("HOLD BACK")
|
||||
# opts = [
|
||||
# 'Option 1',
|
||||
# 'Option 2',
|
||||
# 'Option 3',
|
||||
# 'Option 4'
|
||||
# ]
|
||||
# selected = Console.select(
|
||||
# '>',
|
||||
# 'Select item:',
|
||||
# opts,
|
||||
# header_foreground_color=ForegroundColorEnum.blue,
|
||||
# option_foreground_color=ForegroundColorEnum.green,
|
||||
# cursor_foreground_color=ForegroundColorEnum.red
|
||||
# )
|
||||
# Console.write_line(f'You selected: {selected}')
|
||||
# # test_console()
|
||||
#
|
||||
# Console.write_line()
|
||||
opts = ["Option 1", "Option 2", "Option 3", "Option 4"]
|
||||
selected = Console.select(
|
||||
">",
|
||||
"Select item:",
|
||||
opts,
|
||||
header_foreground_color=ForegroundColorEnum.blue,
|
||||
option_foreground_color=ForegroundColorEnum.green,
|
||||
cursor_foreground_color=ForegroundColorEnum.red,
|
||||
)
|
||||
Console.write_line(f"You selected: {selected}")
|
||||
|
||||
Console.write_line()
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
from typing import Optional
|
||||
|
||||
from cpl.application import ApplicationABC
|
||||
from cpl.auth import KeycloakAdmin
|
||||
from cpl.application.abc.application_abc import ApplicationABC
|
||||
from cpl.auth.keycloak import KeycloakAdmin
|
||||
from cpl.core.console import Console
|
||||
from cpl.core.environment import Environment
|
||||
from cpl.core.log import LoggerABC
|
||||
@@ -16,7 +14,7 @@ class Application(ApplicationABC):
|
||||
def __init__(self, services: ServiceProviderABC):
|
||||
ApplicationABC.__init__(self, services)
|
||||
|
||||
self._logger: Optional[LoggerABC] = None
|
||||
self._logger: LoggerABC = services.get_service(LoggerABC)
|
||||
|
||||
async def test_daos(self):
|
||||
userDao: UserDao = self._services.get_service(UserDao)
|
||||
@@ -30,9 +28,6 @@ class Application(ApplicationABC):
|
||||
|
||||
Console.write_line(await userDao.get_all())
|
||||
|
||||
async def configure(self):
|
||||
self._logger = self._services.get_service(LoggerABC)
|
||||
|
||||
async def main(self):
|
||||
self._logger.debug(f"Host: {Environment.get_host_name()}")
|
||||
self._logger.debug(f"Environment: {Environment.get_environment()}")
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
from application import Application
|
||||
from cpl.application import ApplicationBuilder
|
||||
from custom_permissions import CustomPermissions
|
||||
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()
|
||||
def main():
|
||||
builder = ApplicationBuilder(Application).with_startup(Startup)
|
||||
app = builder.build()
|
||||
|
||||
app.with_permissions(CustomPermissions)
|
||||
app.with_migrations("./scripts")
|
||||
app.with_seeders()
|
||||
app.run()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import asyncio
|
||||
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.run_until_complete(main())
|
||||
main()
|
||||
|
||||
23
tests/custom/database/src/main_simplified.py
Normal file
23
tests/custom/database/src/main_simplified.py
Normal 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()
|
||||
@@ -1,30 +1,26 @@
|
||||
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.permission.permissions_registry import PermissionsRegistry
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.core.environment import Environment
|
||||
from cpl.core.log import Logger, LoggerABC
|
||||
from cpl.database import mysql
|
||||
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 custom_permissions import CustomPermissions
|
||||
from model.city_dao import CityDao
|
||||
from model.user_dao import UserDao
|
||||
|
||||
|
||||
class Startup(AsyncStartupABC):
|
||||
def __init__(self):
|
||||
AsyncStartupABC.__init__(self)
|
||||
class Startup(StartupABC):
|
||||
|
||||
async def configure_configuration(self, configuration: Configuration, environment: Environment):
|
||||
configuration.add_json_file(f"appsettings.json")
|
||||
configuration.add_json_file(f"appsettings.{environment.get_environment()}.json")
|
||||
configuration.add_json_file(f"appsettings.{environment.get_host_name()}.json", optional=True)
|
||||
@staticmethod
|
||||
async def configure_configuration():
|
||||
Configuration.add_json_file(f"appsettings.json")
|
||||
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(auth)
|
||||
services.add_module(permission)
|
||||
@@ -33,13 +29,3 @@ class Startup(AsyncStartupABC):
|
||||
services.add_transient(DataAccessObjectABC, CityDao)
|
||||
|
||||
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()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from cpl.application import ApplicationABC
|
||||
from cpl.core.configuration import ConfigurationABC
|
||||
from cpl.application.abc import ApplicationABC
|
||||
from cpl.core.console.console import Console
|
||||
from cpl.dependency import ServiceProviderABC
|
||||
from cpl.dependency.scope import Scope
|
||||
@@ -11,15 +10,14 @@ from di.tester import Tester
|
||||
|
||||
|
||||
class Application(ApplicationABC):
|
||||
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||
ApplicationABC.__init__(self, config, services)
|
||||
def __init__(self, services: ServiceProviderABC):
|
||||
ApplicationABC.__init__(self, services)
|
||||
|
||||
def _part_of_scoped(self):
|
||||
ts: TestService = self._services.get_service(TestService)
|
||||
ts.run()
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
def configure(self): ...
|
||||
|
||||
def main(self):
|
||||
with self._services.create_scope() as scope:
|
||||
|
||||
@@ -6,7 +6,7 @@ from di.startup import Startup
|
||||
|
||||
def main():
|
||||
app_builder = ApplicationBuilder(Application)
|
||||
app_builder.use_startup(Startup)
|
||||
app_builder.with_startup(Startup)
|
||||
app_builder.build().run()
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
from cpl.application import StartupABC
|
||||
from cpl.core.configuration import ConfigurationABC
|
||||
from cpl.application.abc import StartupABC
|
||||
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.test2_service import Test2Service
|
||||
from di.test_abc import TestABC
|
||||
from di.test_service import TestService
|
||||
from di.di_tester_service import DITesterService
|
||||
from di.tester import Tester
|
||||
|
||||
|
||||
@@ -14,10 +12,9 @@ class Startup(StartupABC):
|
||||
def __init__(self):
|
||||
StartupABC.__init__(self)
|
||||
|
||||
def configure_configuration(self, configuration: ConfigurationABC, environment: Environment) -> ConfigurationABC:
|
||||
return configuration
|
||||
def configure_configuration(self): ...
|
||||
|
||||
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
|
||||
def configure_services(self, services: ServiceCollection) -> ServiceProviderABC:
|
||||
services.add_scoped(TestService)
|
||||
services.add_scoped(DITesterService)
|
||||
|
||||
@@ -25,4 +22,4 @@ class Startup(StartupABC):
|
||||
services.add_singleton(TestABC, Test2Service)
|
||||
services.add_singleton(Tester)
|
||||
|
||||
return services.build_service_provider()
|
||||
return services.build()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
from cpl.core.configuration import ConfigurationABC
|
||||
from cpl.dependency import ServiceProvider, ServiceProviderABC
|
||||
from di.test_service import TestService
|
||||
|
||||
@@ -6,5 +5,5 @@ from di.test_service import TestService
|
||||
class StaticTest:
|
||||
@staticmethod
|
||||
@ServiceProvider.inject
|
||||
def test(services: ServiceProviderABC, config: ConfigurationABC, t1: TestService):
|
||||
def test(services: ServiceProviderABC, t1: TestService):
|
||||
t1.run()
|
||||
|
||||
@@ -6,7 +6,7 @@ from cpl.core.utils.string import String
|
||||
|
||||
class TestService:
|
||||
def __init__(self):
|
||||
self._name = String.random_string(string.ascii_lowercase, 8)
|
||||
self._name = String.random(8)
|
||||
|
||||
def run(self):
|
||||
Console.write_line(f"Im {self._name}")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import time
|
||||
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.console import Console
|
||||
from cpl.dependency import ServiceProviderABC
|
||||
@@ -18,8 +18,8 @@ class Application(ApplicationABC):
|
||||
|
||||
def __init__(self, services: ServiceProviderABC):
|
||||
ApplicationABC.__init__(self, services)
|
||||
self._logger: Optional[LoggerABC] = None
|
||||
self._mailer: Optional[EMailClientABC] = None
|
||||
self._logger = self._services.get_service(LoggerABC)
|
||||
self._mailer = self._services.get_service(EMailClientABC)
|
||||
|
||||
def test_send_mail(self):
|
||||
mail = EMail()
|
||||
@@ -35,10 +35,6 @@ class Application(ApplicationABC):
|
||||
def _wait(time_ms: int):
|
||||
time.sleep(time_ms)
|
||||
|
||||
def configure(self):
|
||||
self._logger = self._services.get_service(LoggerABC)
|
||||
self._mailer = self._services.get_service(EMailClientABC)
|
||||
|
||||
def main(self):
|
||||
self._logger.debug(f"Host: {Environment.get_host_name()}")
|
||||
self._logger.debug(f"Environment: {Environment.get_environment()}")
|
||||
|
||||
@@ -7,9 +7,9 @@ from test_startup_extension import TestStartupExtension
|
||||
|
||||
def main():
|
||||
app_builder = ApplicationBuilder(Application)
|
||||
app_builder.use_startup(Startup)
|
||||
app_builder.use_extension(TestStartupExtension)
|
||||
app_builder.use_extension(TestExtension)
|
||||
app_builder.with_startup(Startup)
|
||||
app_builder.with_extension(TestStartupExtension)
|
||||
app_builder.with_extension(TestExtension)
|
||||
app_builder.build().run()
|
||||
|
||||
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
from cpl import mail
|
||||
from cpl.application import StartupABC
|
||||
from cpl.application.abc import StartupABC
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.dependency import ServiceCollection, ServiceProviderABC
|
||||
from cpl.core.environment import Environment
|
||||
from cpl.core.pipes import IPAddressPipe
|
||||
from cpl.dependency import ServiceCollection
|
||||
from test_service import TestService
|
||||
|
||||
|
||||
class Startup(StartupABC):
|
||||
def __init__(self):
|
||||
StartupABC.__init__(self)
|
||||
|
||||
def configure_configuration(self, config: Configuration, env: Environment):
|
||||
config.add_json_file(f"appsettings.json")
|
||||
config.add_json_file(f"appsettings.{env.get_environment()}.json")
|
||||
config.add_json_file(f"appsettings.{env.get_host_name()}.json", optional=True)
|
||||
@staticmethod
|
||||
def configure_configuration():
|
||||
Configuration.add_json_file(f"appsettings.json")
|
||||
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_module(mail)
|
||||
services.add_transient(IPAddressPipe)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
from cpl.application import ApplicationExtensionABC
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.application.abc import ApplicationExtensionABC
|
||||
from cpl.core.console import Console
|
||||
from cpl.dependency import ServiceProviderABC
|
||||
|
||||
|
||||
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")
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
from cpl.application import StartupExtensionABC
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.application.abc import StartupExtensionABC
|
||||
from cpl.core.console import Console
|
||||
from cpl.dependency import ServiceCollection
|
||||
from cpl.core.environment import Environment
|
||||
|
||||
|
||||
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")
|
||||
|
||||
def configure_services(self, services: ServiceCollection, env: Environment):
|
||||
@staticmethod
|
||||
def configure_services(services: ServiceCollection):
|
||||
Console.write_line("services")
|
||||
|
||||
@@ -18,8 +18,7 @@ class Application(ApplicationABC):
|
||||
self._translation.load_by_settings(config.get_configuration(TranslationSettings))
|
||||
self._translation.set_default_lang("de")
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
def configure(self): ...
|
||||
|
||||
def main(self):
|
||||
Console.write_line(self._translate.transform("main.text.hello_world"))
|
||||
|
||||
@@ -6,7 +6,7 @@ from translation.startup import Startup
|
||||
|
||||
def main():
|
||||
app_builder = ApplicationBuilder(Application)
|
||||
app_builder.use_startup(Startup)
|
||||
app_builder.with_startup(Startup)
|
||||
app_builder.build().run()
|
||||
|
||||
|
||||
|
||||
@@ -14,4 +14,4 @@ class Startup(StartupABC):
|
||||
|
||||
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
|
||||
services.add_translation()
|
||||
return services.build_service_provider()
|
||||
return services.build()
|
||||
|
||||
@@ -13,8 +13,7 @@ class Application(ApplicationABC):
|
||||
def __init__(self, config: ConfigurationABC, services: ServiceProviderABC):
|
||||
ApplicationABC.__init__(self, config, services)
|
||||
|
||||
def configure(self):
|
||||
pass
|
||||
def configure(self): ...
|
||||
|
||||
def main(self):
|
||||
runner = unittest.TextTestRunner()
|
||||
|
||||
@@ -2,8 +2,6 @@ from unittests_cli.abc.command_test_case import CommandTestCase
|
||||
|
||||
|
||||
class CustomTestCase(CommandTestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
def setUp(self): ...
|
||||
|
||||
def test_equal(self):
|
||||
pass
|
||||
def test_equal(self): ...
|
||||
|
||||
@@ -26,8 +26,7 @@ class VersionTestCase(CommandTestCase):
|
||||
self._block_packages = ""
|
||||
self._name = "CPL CLI"
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
def setUp(self): ...
|
||||
|
||||
def _get_version_output(self, version: str):
|
||||
index = 0
|
||||
|
||||
@@ -61,7 +61,7 @@ class ConfigurationTestCase(unittest.TestCase):
|
||||
self._config.create_console_argument(ArgumentTypeEnum.Variable, "", "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()
|
||||
|
||||
self.assertEqual("test", self._config.get_configuration("var"))
|
||||
|
||||
@@ -31,28 +31,28 @@ class ConsoleArgumentsTestCase(unittest.TestCase):
|
||||
def test_flag(self):
|
||||
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)
|
||||
|
||||
def test_var(self):
|
||||
sys.argv.append("var=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.assertIsNone(self._config.get_configuration("var1"))
|
||||
|
||||
def test_exec(self):
|
||||
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()
|
||||
|
||||
def test_exec_with_one_flag(self):
|
||||
sys.argv.append("exec")
|
||||
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.assertIn("dev", self._config.additional_arguments)
|
||||
|
||||
@@ -60,7 +60,7 @@ class ConsoleArgumentsTestCase(unittest.TestCase):
|
||||
sys.argv.append("exec")
|
||||
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.assertIn("dev", self._config.additional_arguments)
|
||||
|
||||
@@ -69,7 +69,7 @@ class ConsoleArgumentsTestCase(unittest.TestCase):
|
||||
sys.argv.append("--dev")
|
||||
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.assertIn("dev", self._config.additional_arguments)
|
||||
self.assertIn("virtual", self._config.additional_arguments)
|
||||
|
||||
@@ -50,7 +50,7 @@ class ServiceCollectionTestCase(unittest.TestCase):
|
||||
self._sc.add_singleton(Mock)
|
||||
service = self._sc._service_descriptors[0]
|
||||
self.assertIsNone(service.implementation)
|
||||
sp = self._sc.build_service_provider()
|
||||
sp = self._sc.build()
|
||||
self.assertTrue(isinstance(sp, ServiceProviderABC))
|
||||
self.assertTrue(isinstance(sp.get_service(Mock), Mock))
|
||||
self.assertIsNotNone(service.implementation)
|
||||
|
||||
@@ -39,7 +39,7 @@ class ServiceProviderTestCase(unittest.TestCase):
|
||||
.add_singleton(TestService)
|
||||
.add_transient(DifferentService)
|
||||
.add_scoped(MoreDifferentService)
|
||||
.build_service_provider()
|
||||
.build()
|
||||
)
|
||||
|
||||
count = self._services.get_service(ServiceCount)
|
||||
|
||||
@@ -4,8 +4,7 @@ from cpl.core.pipes import BoolPipe
|
||||
|
||||
|
||||
class BoolPipeTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
def setUp(self): ...
|
||||
|
||||
def test_transform(self):
|
||||
self.assertEqual("true", BoolPipe.to_str(True))
|
||||
|
||||
@@ -4,8 +4,7 @@ from cpl.core.pipes import IPAddressPipe
|
||||
|
||||
|
||||
class IPAddressTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
def setUp(self): ...
|
||||
|
||||
def test_transform(self):
|
||||
self.assertEqual("192.168.178.1", IPAddressPipe.to_str([192, 168, 178, 1]))
|
||||
|
||||
@@ -4,8 +4,7 @@ from cpl.core.utils import CredentialManager
|
||||
|
||||
|
||||
class CredentialManagerTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
def setUp(self): ...
|
||||
|
||||
def test_encrypt(self):
|
||||
self.assertEqual("ZkVjSkplQUx4aW1zWHlPbA==", CredentialManager.encrypt("fEcJJeALximsXyOl"))
|
||||
|
||||
@@ -18,8 +18,7 @@ class TestClass:
|
||||
|
||||
|
||||
class JSONProcessorTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
def setUp(self): ...
|
||||
|
||||
def test_process(self):
|
||||
test_dict = {
|
||||
|
||||
@@ -5,8 +5,7 @@ from cpl.core.utils import String
|
||||
|
||||
|
||||
class StringTestCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
def setUp(self): ...
|
||||
|
||||
def test_convert_to_camel_case(self):
|
||||
expected = "HelloWorld"
|
||||
|
||||
@@ -20,8 +20,7 @@ class TranslationTestCase(unittest.TestCase):
|
||||
self._translation.set_default_lang("de")
|
||||
self._translate = TranslatePipe(self._translation)
|
||||
|
||||
def cleanUp(self):
|
||||
pass
|
||||
def cleanUp(self): ...
|
||||
|
||||
def test_service(self):
|
||||
self.assertEqual("Hallo Welt", self._translation.translate("main.text.hello_world"))
|
||||
|
||||
Reference in New Issue
Block a user