Compare commits
2 Commits
2025.09.16
...
2025.09.16
| Author | SHA1 | Date | |
|---|---|---|---|
| 58dbd3ed1e | |||
| cd7dfaf2b4 |
@@ -1,6 +1,6 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from cpl.dependency.service_collection_abc import ServiceCollectionABC
|
||||
from cpl.dependency.service_collection import ServiceCollection
|
||||
|
||||
|
||||
class AsyncStartupABC(ABC):
|
||||
@@ -15,9 +15,9 @@ class AsyncStartupABC(ABC):
|
||||
r"""Creates configuration of application"""
|
||||
|
||||
@abstractmethod
|
||||
async def configure_services(self, service: ServiceCollectionABC):
|
||||
async def configure_services(self, service: ServiceCollection):
|
||||
r"""Creates service provider
|
||||
|
||||
Parameter:
|
||||
services: :class:`cpl.dependency.service_collection_abc`
|
||||
services: :class:`cpl.dependency.service_collection`
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from cpl.core.configuration.configuration import Configuration
|
||||
from cpl.dependency.service_collection_abc import ServiceCollectionABC
|
||||
from cpl.dependency.service_collection import ServiceCollection
|
||||
from cpl.core.environment.environment import Environment
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ class AsyncStartupExtensionABC(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
async def configure_services(self, service: ServiceCollectionABC, env: Environment):
|
||||
async def configure_services(self, service: ServiceCollection, env: Environment):
|
||||
r"""Creates service provider
|
||||
|
||||
Parameter:
|
||||
services: :class:`cpl.dependency.service_collection_abc`
|
||||
services: :class:`cpl.dependency.service_collection`
|
||||
env: :class:`cpl.core.environment.application_environment_abc`
|
||||
"""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.dependency.service_collection_abc import ServiceCollectionABC
|
||||
from cpl.dependency.service_collection import ServiceCollection
|
||||
from cpl.core.environment import Environment
|
||||
|
||||
|
||||
@@ -22,10 +22,10 @@ class StartupABC(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def configure_services(self, service: ServiceCollectionABC, env: Environment):
|
||||
def configure_services(self, service: ServiceCollection, env: Environment):
|
||||
r"""Creates service provider
|
||||
|
||||
Parameter:
|
||||
services: :class:`cpl.dependency.service_collection_abc`
|
||||
services: :class:`cpl.dependency.service_collection`
|
||||
env: :class:`cpl.core.environment.application_environment_abc`
|
||||
"""
|
||||
|
||||
@@ -2,7 +2,7 @@ from abc import ABC, abstractmethod
|
||||
|
||||
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.dependency.service_collection_abc import ServiceCollectionABC
|
||||
from cpl.dependency.service_collection import ServiceCollection
|
||||
|
||||
from cpl.core.environment.environment import Environment
|
||||
|
||||
@@ -24,10 +24,10 @@ class StartupExtensionABC(ABC):
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def configure_services(self, service: ServiceCollectionABC, env: Environment):
|
||||
def configure_services(self, service: ServiceCollection, env: Environment):
|
||||
r"""Creates service provider
|
||||
|
||||
Parameter:
|
||||
services: :class:`cpl.dependency.service_collection_abc`
|
||||
services: :class:`cpl.dependency.service_collection`
|
||||
env: :class:`cpl.core.environment.application_environment_abc`
|
||||
"""
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
from .background_color_enum import BackgroundColorEnum
|
||||
from .console import Console
|
||||
from .console_call import ConsoleCall
|
||||
from ._call import ConsoleCall
|
||||
from .foreground_color_enum import ForegroundColorEnum
|
||||
from .spinner_thread import SpinnerThread
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import os
|
||||
import sys
|
||||
import threading
|
||||
import multiprocessing
|
||||
import time
|
||||
from multiprocessing import Process
|
||||
|
||||
from termcolor import colored
|
||||
|
||||
@@ -9,8 +10,8 @@ from cpl.core.console.background_color_enum import BackgroundColorEnum
|
||||
from cpl.core.console.foreground_color_enum import ForegroundColorEnum
|
||||
|
||||
|
||||
class SpinnerThread(threading.Thread):
|
||||
r"""Thread to show spinner in terminal
|
||||
class Spinner(Process):
|
||||
r"""Process to show spinner in terminal
|
||||
|
||||
Parameter:
|
||||
msg_len: :class:`int`
|
||||
@@ -22,7 +23,7 @@ class SpinnerThread(threading.Thread):
|
||||
"""
|
||||
|
||||
def __init__(self, msg_len: int, foreground_color: ForegroundColorEnum, background_color: BackgroundColorEnum):
|
||||
threading.Thread.__init__(self)
|
||||
Process.__init__(self)
|
||||
|
||||
self._msg_len = msg_len
|
||||
self._foreground_color = foreground_color
|
||||
@@ -50,29 +51,26 @@ class SpinnerThread(threading.Thread):
|
||||
return color_args
|
||||
|
||||
def run(self) -> None:
|
||||
r"""Entry point of thread, shows the spinner"""
|
||||
r"""Entry point of process, shows the spinner"""
|
||||
columns = 0
|
||||
if sys.platform == "win32":
|
||||
columns = os.get_terminal_size().columns
|
||||
else:
|
||||
term_rows, term_columns = os.popen("stty size", "r").read().split()
|
||||
values = os.popen("stty size", "r").read().split()
|
||||
term_rows, term_columns = values if len(values) == 2 else (0, 0)
|
||||
columns = int(term_columns)
|
||||
|
||||
end_msg = "done"
|
||||
end_msg_pos = columns - self._msg_len - len(end_msg)
|
||||
if end_msg_pos > 0:
|
||||
print(f'{"" : >{end_msg_pos}}', end="")
|
||||
|
||||
padding = columns - self._msg_len - len(end_msg)
|
||||
if padding > 0:
|
||||
print(f'{"" : >{padding}}', end="")
|
||||
else:
|
||||
print("", end="")
|
||||
|
||||
first = True
|
||||
spinner = self._spinner()
|
||||
while self._is_spinning:
|
||||
if first:
|
||||
first = False
|
||||
print(colored(f"{next(spinner): >{len(end_msg) - 1}}", *self._get_color_args()), end="")
|
||||
else:
|
||||
print(colored(f"{next(spinner): >{len(end_msg)}}", *self._get_color_args()), end="")
|
||||
print(colored(f"{next(spinner): >{len(end_msg)}}", *self._get_color_args()), end="")
|
||||
time.sleep(0.1)
|
||||
back = ""
|
||||
for i in range(0, len(end_msg)):
|
||||
@@ -84,9 +82,10 @@ class SpinnerThread(threading.Thread):
|
||||
if not self._exit:
|
||||
print(colored(end_msg, *self._get_color_args()), end="")
|
||||
|
||||
def stop_spinning(self):
|
||||
def stop(self):
|
||||
r"""Stops the spinner"""
|
||||
self._is_spinning = False
|
||||
super().terminate()
|
||||
time.sleep(0.1)
|
||||
|
||||
def exit(self):
|
||||
@@ -10,9 +10,9 @@ from tabulate import tabulate
|
||||
from termcolor import colored
|
||||
|
||||
from cpl.core.console.background_color_enum import BackgroundColorEnum
|
||||
from cpl.core.console.console_call import ConsoleCall
|
||||
from cpl.core.console._call import ConsoleCall
|
||||
from cpl.core.console.foreground_color_enum import ForegroundColorEnum
|
||||
from cpl.core.console.spinner_thread import SpinnerThread
|
||||
from cpl.core.console._spinner import Spinner
|
||||
|
||||
|
||||
class Console:
|
||||
@@ -464,7 +464,7 @@ class Console:
|
||||
cls.set_hold_back(True)
|
||||
spinner = None
|
||||
if not cls._disabled:
|
||||
spinner = SpinnerThread(len(message), spinner_foreground_color, spinner_background_color)
|
||||
spinner = Spinner(len(message), spinner_foreground_color, spinner_background_color)
|
||||
spinner.start()
|
||||
|
||||
return_value = None
|
||||
@@ -476,7 +476,7 @@ class Console:
|
||||
cls.close()
|
||||
|
||||
if spinner is not None:
|
||||
spinner.stop_spinning()
|
||||
spinner.stop()
|
||||
cls.set_hold_back(False)
|
||||
|
||||
cls.set_foreground_color(ForegroundColorEnum.default)
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
import multiprocessing
|
||||
import os
|
||||
from datetime import datetime
|
||||
from typing import Self
|
||||
|
||||
from cpl.core.console import Console
|
||||
from cpl.core.log.log_level_enum import LogLevelEnum
|
||||
|
||||
|
||||
class LogWriter:
|
||||
_instance = None
|
||||
|
||||
# ANSI color codes for different log levels
|
||||
_COLORS = {
|
||||
LogLevelEnum.trace: "\033[37m", # Light Gray
|
||||
LogLevelEnum.debug: "\033[94m", # Blue
|
||||
LogLevelEnum.info: "\033[92m", # Green
|
||||
LogLevelEnum.warning: "\033[93m", # Yellow
|
||||
LogLevelEnum.error: "\033[91m", # Red
|
||||
LogLevelEnum.fatal: "\033[95m", # Magenta
|
||||
}
|
||||
|
||||
def __init__(self, file_prefix: str, level: LogLevelEnum = LogLevelEnum.info):
|
||||
self._file_prefix = file_prefix
|
||||
self._level = level
|
||||
|
||||
self._queue = multiprocessing.Queue()
|
||||
self._process = multiprocessing.Process(target=self._log_worker, daemon=True)
|
||||
|
||||
self._create_log_dir()
|
||||
self._process.start()
|
||||
|
||||
@property
|
||||
def level(self) -> LogLevelEnum:
|
||||
return self._level
|
||||
|
||||
@level.setter
|
||||
def level(self, value: LogLevelEnum):
|
||||
assert isinstance(value, LogLevelEnum), "Log level must be an instance of LogLevelEnum"
|
||||
self._level = value
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls, file_prefix: str, level: LogLevelEnum = LogLevelEnum.info) -> Self:
|
||||
if cls._instance is None:
|
||||
cls._instance = LogWriter(file_prefix, level)
|
||||
return cls._instance
|
||||
|
||||
@staticmethod
|
||||
def _create_log_dir():
|
||||
if os.path.exists("logs"):
|
||||
return
|
||||
|
||||
os.makedirs("logs")
|
||||
|
||||
def _log_worker(self):
|
||||
"""Worker process that writes log messages from the queue to the file."""
|
||||
while True:
|
||||
content = self._queue.get()
|
||||
if content is None: # Shutdown signal
|
||||
break
|
||||
self._write_log_to_file(content)
|
||||
Console.write_line(f"{self._COLORS.get(self._level, '\033[0m')}{content}\033[0m")
|
||||
|
||||
@property
|
||||
def log_file(self):
|
||||
return f"logs/{self._file_prefix}_{datetime.now().strftime('%Y-%m-%d')}.log"
|
||||
|
||||
def _ensure_file_size(self):
|
||||
log_file = self.log_file
|
||||
if not os.path.exists(log_file) or os.path.getsize(log_file) <= 0.5 * 1024 * 1024:
|
||||
return
|
||||
|
||||
# if exists and size is greater than 300MB, create a new file
|
||||
os.rename(
|
||||
log_file,
|
||||
f"{log_file.split('.log')[0]}_{datetime.now().strftime('%H-%M-%S')}.log",
|
||||
)
|
||||
|
||||
def _write_log_to_file(self, content: str):
|
||||
self._ensure_file_size()
|
||||
with open(self.log_file, "a") as log_file:
|
||||
log_file.write(content + "\n")
|
||||
log_file.close()
|
||||
|
||||
def log(self, content: str):
|
||||
"""Enqueue log message without blocking main app."""
|
||||
self._queue.put(content)
|
||||
|
||||
def close(self):
|
||||
"""Gracefully stop the logging process."""
|
||||
self._queue.put(None)
|
||||
self._process.join()
|
||||
@@ -3,7 +3,6 @@ import traceback
|
||||
from datetime import datetime
|
||||
|
||||
from cpl.core.console import Console
|
||||
from cpl.core.log._log_writer import LogWriter
|
||||
from cpl.core.log.log_level_enum import LogLevelEnum
|
||||
from cpl.core.log.logger_abc import LoggerABC
|
||||
from cpl.core.typing import Messages, Source
|
||||
@@ -13,6 +12,16 @@ class Logger(LoggerABC):
|
||||
_level = LogLevelEnum.info
|
||||
_levels = [x for x in LogLevelEnum]
|
||||
|
||||
# ANSI color codes for different log levels
|
||||
_COLORS = {
|
||||
LogLevelEnum.trace: "\033[37m", # Light Gray
|
||||
LogLevelEnum.debug: "\033[94m", # Blue
|
||||
LogLevelEnum.info: "\033[92m", # Green
|
||||
LogLevelEnum.warning: "\033[93m", # Yellow
|
||||
LogLevelEnum.error: "\033[91m", # Red
|
||||
LogLevelEnum.fatal: "\033[95m", # Magenta
|
||||
}
|
||||
|
||||
def __init__(self, source: Source, file_prefix: str = None):
|
||||
LoggerABC.__init__(self)
|
||||
assert source is not None and source != "", "Source cannot be None or empty"
|
||||
@@ -22,7 +31,18 @@ class Logger(LoggerABC):
|
||||
file_prefix = "app"
|
||||
|
||||
self._file_prefix = file_prefix
|
||||
self._writer = LogWriter.get_instance(self._file_prefix)
|
||||
self._create_log_dir()
|
||||
|
||||
@property
|
||||
def log_file(self):
|
||||
return f"logs/{self._file_prefix}_{datetime.now().strftime('%Y-%m-%d')}.log"
|
||||
|
||||
@staticmethod
|
||||
def _create_log_dir():
|
||||
if os.path.exists("logs"):
|
||||
return
|
||||
|
||||
os.makedirs("logs")
|
||||
|
||||
@classmethod
|
||||
def set_level(cls, level: LogLevelEnum):
|
||||
@@ -31,6 +51,24 @@ class Logger(LoggerABC):
|
||||
else:
|
||||
raise ValueError(f"Invalid log level: {level}")
|
||||
|
||||
@staticmethod
|
||||
def _ensure_file_size(log_file: str):
|
||||
if not os.path.exists(log_file) or os.path.getsize(log_file) <= 0.5 * 1024 * 1024:
|
||||
return
|
||||
|
||||
# if exists and size is greater than 300MB, create a new file
|
||||
os.rename(
|
||||
log_file,
|
||||
f"{log_file.split('.log')[0]}_{datetime.now().strftime('%H-%M-%S')}.log",
|
||||
)
|
||||
|
||||
def _write_log_to_file(self, content: str):
|
||||
file = self.log_file
|
||||
self._ensure_file_size(file)
|
||||
with open(file, "a") as log_file:
|
||||
log_file.write(content + "\n")
|
||||
log_file.close()
|
||||
|
||||
def _log(self, level: LogLevelEnum, *messages: Messages):
|
||||
try:
|
||||
if self._levels.index(level) < self._levels.index(self._level):
|
||||
@@ -39,7 +77,8 @@ class Logger(LoggerABC):
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
|
||||
formatted_message = self._format_message(level.value, timestamp, *messages)
|
||||
|
||||
self._writer.log(formatted_message)
|
||||
self._write_log_to_file(formatted_message)
|
||||
Console.write_line(f"{self._COLORS.get(self._level, '\033[0m')}{formatted_message}\033[0m")
|
||||
except Exception as e:
|
||||
print(f"Error while logging: {e} -> {traceback.format_exc()}")
|
||||
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
from .database_settings_name_enum import DatabaseSettingsNameEnum
|
||||
from cpl.dependency import ServiceCollection as _ServiceCollection
|
||||
from . import mysql
|
||||
from .database_settings import DatabaseSettings
|
||||
from .database_settings_name_enum import DatabaseSettingsNameEnum
|
||||
from .mysql.context import DatabaseContextABC, DatabaseContext
|
||||
from .table_abc import TableABC
|
||||
|
||||
|
||||
def add_mysql(collection: _ServiceCollection):
|
||||
from cpl.core.console import Console
|
||||
from cpl.core.configuration import Configuration
|
||||
|
||||
try:
|
||||
collection.add_singleton(DatabaseContextABC, DatabaseContext)
|
||||
database_context = collection.build_service_provider().get_service(DatabaseContextABC)
|
||||
|
||||
db_settings: DatabaseSettings = Configuration.get(DatabaseSettings)
|
||||
database_context.connect(db_settings)
|
||||
except ImportError as e:
|
||||
Console.error("cpl-translation is not installed", str(e))
|
||||
|
||||
|
||||
_ServiceCollection.with_module(add_mysql, mysql.__name__)
|
||||
|
||||
0
src/cpl-database/cpl/database/mysql/__init__.py
Normal file
0
src/cpl-database/cpl/database/mysql/__init__.py
Normal file
@@ -4,7 +4,7 @@ import mysql.connector as sql
|
||||
from mysql.connector.abstracts import MySQLConnectionAbstract
|
||||
from mysql.connector.cursor import MySQLCursorBuffered
|
||||
|
||||
from cpl.database.connection.database_connection_abc import DatabaseConnectionABC
|
||||
from cpl.database.mysql.connection.database_connection_abc import DatabaseConnectionABC
|
||||
from cpl.database.database_settings import DatabaseSettings
|
||||
from cpl.core.utils.credential_manager import CredentialManager
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
from typing import Optional
|
||||
|
||||
|
||||
from cpl.database.connection.database_connection import DatabaseConnection
|
||||
from cpl.database.connection.database_connection_abc import DatabaseConnectionABC
|
||||
from cpl.database.context.database_context_abc import DatabaseContextABC
|
||||
from cpl.database.mysql.connection.database_connection import DatabaseConnection
|
||||
from cpl.database.mysql.connection.database_connection_abc import DatabaseConnectionABC
|
||||
from cpl.database.mysql.context.database_context_abc import DatabaseContextABC
|
||||
from cpl.database.database_settings import DatabaseSettings
|
||||
from mysql.connector.cursor import MySQLCursorBuffered
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
from .scope import Scope
|
||||
from .scope_abc import ScopeABC
|
||||
from .service_collection import ServiceCollection
|
||||
from .service_collection_abc import ServiceCollectionABC
|
||||
from .service_descriptor import ServiceDescriptor
|
||||
from .service_lifetime_enum import ServiceLifetimeEnum
|
||||
from .service_provider import ServiceProvider
|
||||
|
||||
@@ -1,24 +1,26 @@
|
||||
from typing import Union, Type, Callable, Optional
|
||||
|
||||
from cpl.database.context.database_context_abc import DatabaseContextABC
|
||||
from cpl.database.database_settings import DatabaseSettings
|
||||
from cpl.dependency.service_collection_abc import ServiceCollectionABC
|
||||
from cpl.dependency.service_descriptor import ServiceDescriptor
|
||||
from cpl.dependency.service_lifetime_enum import ServiceLifetimeEnum
|
||||
from cpl.dependency.service_provider import ServiceProvider
|
||||
from cpl.dependency.service_provider_abc import ServiceProviderABC
|
||||
from cpl.core.log.logger import Logger
|
||||
from cpl.core.log.logger_abc import LoggerABC
|
||||
from cpl.core.pipes.pipe_abc import PipeABC
|
||||
from cpl.core.typing import T, Service
|
||||
from cpl.dependency.service_descriptor import ServiceDescriptor
|
||||
from cpl.dependency.service_lifetime_enum import ServiceLifetimeEnum
|
||||
from cpl.dependency.service_provider import ServiceProvider
|
||||
from cpl.dependency.service_provider_abc import ServiceProviderABC
|
||||
|
||||
|
||||
class ServiceCollection(ServiceCollectionABC):
|
||||
class ServiceCollection:
|
||||
r"""Representation of the collection of services"""
|
||||
|
||||
_modules: dict[str, Callable] = {}
|
||||
|
||||
@classmethod
|
||||
def with_module(cls, func: Callable, name: str = None):
|
||||
cls._modules[func.__name__ if name is None else name] = func
|
||||
return cls
|
||||
|
||||
def __init__(self):
|
||||
ServiceCollectionABC.__init__(self)
|
||||
self._database_context: Optional[DatabaseContextABC] = None
|
||||
self._service_descriptors: list[ServiceDescriptor] = []
|
||||
|
||||
def _add_descriptor(self, service: Union[type, object], lifetime: ServiceLifetimeEnum, base_type: Callable = None):
|
||||
@@ -44,10 +46,19 @@ class ServiceCollection(ServiceCollectionABC):
|
||||
|
||||
return self
|
||||
|
||||
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
|
||||
self.add_singleton(DatabaseContextABC, db_context_type)
|
||||
self._database_context = self.build_service_provider().get_service(DatabaseContextABC)
|
||||
self._database_context.connect(db_settings)
|
||||
def add_module(self, module: str | object):
|
||||
if not isinstance(module, str):
|
||||
module = module.__name__
|
||||
|
||||
if module not in self._modules:
|
||||
raise ValueError(f"Module {module} not found")
|
||||
|
||||
self._modules[module](self)
|
||||
|
||||
# def add_mysql(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
|
||||
# self.add_singleton(DatabaseContextABC, db_context_type)
|
||||
# self._database_context = self.build_service_provider().get_service(DatabaseContextABC)
|
||||
# self._database_context.connect(db_settings)
|
||||
|
||||
def add_logging(self):
|
||||
self.add_transient(LoggerABC, Logger)
|
||||
@@ -71,6 +82,6 @@ class ServiceCollection(ServiceCollectionABC):
|
||||
return self
|
||||
|
||||
def build_service_provider(self) -> ServiceProviderABC:
|
||||
sp = ServiceProvider(self._service_descriptors, self._database_context)
|
||||
sp = ServiceProvider(self._service_descriptors)
|
||||
ServiceProviderABC.set_global_provider(sp)
|
||||
return sp
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
from abc import abstractmethod, ABC
|
||||
from typing import Type
|
||||
|
||||
from cpl.database.context.database_context_abc import DatabaseContextABC
|
||||
from cpl.database.database_settings import DatabaseSettings
|
||||
from cpl.dependency.service_provider_abc import ServiceProviderABC
|
||||
from cpl.core.typing import T, Source
|
||||
|
||||
|
||||
class ServiceCollectionABC(ABC):
|
||||
r"""ABC for the class :class:`cpl.dependency.service_collection.ServiceCollection`"""
|
||||
|
||||
@abstractmethod
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def add_db_context(self, db_context_type: Type[DatabaseContextABC], db_settings: DatabaseSettings):
|
||||
r"""Adds database context
|
||||
|
||||
Parameter:
|
||||
db_context: Type[:class:`cpl.database.context.database_context_abc.DatabaseContextABC`]
|
||||
Database context
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def add_logging(self):
|
||||
r"""Adds the CPL internal logger"""
|
||||
|
||||
@abstractmethod
|
||||
def add_pipes(self):
|
||||
r"""Adds the CPL internal pipes as transient"""
|
||||
|
||||
def add_translation(self):
|
||||
r"""Adds the CPL translation"""
|
||||
raise NotImplementedError("You should install and use the cpl-translation package")
|
||||
|
||||
def add_mail(self):
|
||||
r"""Adds the CPL mail"""
|
||||
raise NotImplementedError("You should install and use the cpl-mail package")
|
||||
|
||||
@abstractmethod
|
||||
def add_transient(self, service_type: T, service: T = None) -> "ServiceCollectionABC":
|
||||
r"""Adds a service with transient lifetime
|
||||
|
||||
Parameter:
|
||||
service_type: :class:`Type`
|
||||
Type of the service
|
||||
service: :class:`Callable`
|
||||
Object of the service
|
||||
|
||||
Returns:
|
||||
self: :class:`cpl.dependency.service_collection_abc.ServiceCollectionABC`
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def add_scoped(self, service_type: T, service: T = None) -> "ServiceCollectionABC":
|
||||
r"""Adds a service with scoped lifetime
|
||||
|
||||
Parameter:
|
||||
service_type: :class:`Type`
|
||||
Type of the service
|
||||
service: :class:`Callable`
|
||||
Object of the service
|
||||
|
||||
Returns:
|
||||
self: :class:`cpl.dependency.service_collection_abc.ServiceCollectionABC`
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def add_singleton(self, service_type: T, service: T = None) -> "ServiceCollectionABC":
|
||||
r"""Adds a service with singleton lifetime
|
||||
|
||||
Parameter:
|
||||
service_type: :class:`Type`
|
||||
Type of the service
|
||||
service: :class:`Callable`
|
||||
Object of the service
|
||||
|
||||
Returns:
|
||||
self: :class:`cpl.dependency.service_collection_abc.ServiceCollectionABC`
|
||||
"""
|
||||
|
||||
@abstractmethod
|
||||
def build_service_provider(self) -> ServiceProviderABC:
|
||||
r"""Creates instance of the service provider
|
||||
|
||||
Returns:
|
||||
Object of type :class:`cpl.dependency.service_provider_abc.ServiceProviderABC`
|
||||
"""
|
||||
@@ -5,7 +5,6 @@ from typing import Optional
|
||||
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.core.configuration.configuration_model_abc import ConfigurationModelABC
|
||||
from cpl.database.context.database_context_abc import DatabaseContextABC
|
||||
from cpl.core.environment import Environment
|
||||
from cpl.core.typing import T, R, Source
|
||||
from cpl.dependency.scope_abc import ScopeABC
|
||||
@@ -31,12 +30,10 @@ class ServiceProvider(ServiceProviderABC):
|
||||
def __init__(
|
||||
self,
|
||||
service_descriptors: list[ServiceDescriptor],
|
||||
db_context: Optional[DatabaseContextABC],
|
||||
):
|
||||
ServiceProviderABC.__init__(self)
|
||||
|
||||
self._service_descriptors: list[ServiceDescriptor] = service_descriptors
|
||||
self._database_context = db_context
|
||||
self._scope: Optional[ScopeABC] = None
|
||||
|
||||
def _find_service(self, service_type: type) -> Optional[ServiceDescriptor]:
|
||||
@@ -95,9 +92,6 @@ class ServiceProvider(ServiceProviderABC):
|
||||
elif issubclass(parameter.annotation, Environment):
|
||||
params.append(Environment)
|
||||
|
||||
elif issubclass(parameter.annotation, DatabaseContextABC):
|
||||
params.append(self._database_context)
|
||||
|
||||
elif issubclass(parameter.annotation, ConfigurationModelABC):
|
||||
params.append(Configuration.get(parameter.annotation))
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from cpl.dependency import ServiceCollection as _ServiceCollection
|
||||
from .abc.email_client_abc import EMailClientABC
|
||||
from .email_client import EMailClient
|
||||
from .email_client_settings import EMailClientSettings
|
||||
@@ -6,21 +7,15 @@ from .email_model import EMail
|
||||
from .mail_logger import MailLogger
|
||||
|
||||
|
||||
def add_mail(self):
|
||||
def add_mail(collection: _ServiceCollection):
|
||||
from cpl.core.console import Console
|
||||
from cpl.core.log import LoggerABC
|
||||
|
||||
try:
|
||||
self.add_singleton(EMailClientABC, EMailClient)
|
||||
self.add_transient(LoggerABC, MailLogger)
|
||||
collection.add_singleton(EMailClientABC, EMailClient)
|
||||
collection.add_transient(LoggerABC, MailLogger)
|
||||
except ImportError as e:
|
||||
Console.error("cpl-translation is not installed", str(e))
|
||||
|
||||
|
||||
def init():
|
||||
from cpl.dependency import ServiceCollection
|
||||
|
||||
ServiceCollection.add_mail = add_mail
|
||||
|
||||
|
||||
init()
|
||||
_ServiceCollection.with_module(add_mail, __name__)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from cpl.dependency import ServiceCollection as _ServiceCollection
|
||||
from .translate_pipe import TranslatePipe
|
||||
from .translation_service import TranslationService
|
||||
from .translation_service_abc import TranslationServiceABC
|
||||
from .translation_settings import TranslationSettings
|
||||
|
||||
|
||||
def add_translation(self):
|
||||
def add_translation(collection: _ServiceCollection):
|
||||
from cpl.core.console import Console
|
||||
from cpl.core.pipes import PipeABC
|
||||
from cpl.translation.translate_pipe import TranslatePipe
|
||||
@@ -12,16 +13,10 @@ def add_translation(self):
|
||||
from cpl.translation.translation_service_abc import TranslationServiceABC
|
||||
|
||||
try:
|
||||
self.add_singleton(TranslationServiceABC, TranslationService)
|
||||
self.add_transient(PipeABC, TranslatePipe)
|
||||
collection.add_singleton(TranslationServiceABC, TranslationService)
|
||||
collection.add_transient(PipeABC, TranslatePipe)
|
||||
except ImportError as e:
|
||||
Console.error("cpl-translation is not installed", str(e))
|
||||
|
||||
|
||||
def init():
|
||||
from cpl.dependency import ServiceCollection
|
||||
|
||||
ServiceCollection.add_translation = add_translation
|
||||
|
||||
|
||||
init()
|
||||
_ServiceCollection.with_module(add_translation, __name__)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from cpl.application.async_startup_abc import AsyncStartupABC
|
||||
from cpl.core.configuration import ConfigurationABC
|
||||
from cpl.dependency import ServiceProviderABC, ServiceCollectionABC
|
||||
from cpl.dependency import ServiceProviderABC, ServiceCollection
|
||||
from cpl.core.environment import Environment
|
||||
|
||||
|
||||
@@ -13,5 +13,5 @@ class Startup(AsyncStartupABC):
|
||||
) -> ConfigurationABC:
|
||||
return configuration
|
||||
|
||||
async def configure_services(self, services: ServiceCollectionABC, environment: Environment) -> ServiceProviderABC:
|
||||
async def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
|
||||
return services.build_service_provider()
|
||||
|
||||
@@ -25,6 +25,7 @@ if __name__ == "__main__":
|
||||
Console.spinner(
|
||||
"Test:", test_spinner, spinner_foreground_color=ForegroundColorEnum.cyan, text_foreground_color="green"
|
||||
)
|
||||
Console.write_line("HOLD BACK")
|
||||
# opts = [
|
||||
# 'Option 1',
|
||||
# 'Option 2',
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
from cpl.database import DatabaseSettings
|
||||
from cpl.database.context import DatabaseContext
|
||||
|
||||
|
||||
class DBContext(DatabaseContext):
|
||||
def __init__(self):
|
||||
DatabaseContext.__init__(self)
|
||||
@@ -1,5 +1,5 @@
|
||||
from cpl.core.console import Console
|
||||
from cpl.database.context import DatabaseContextABC
|
||||
from cpl.database.mysql.context import DatabaseContextABC
|
||||
|
||||
from .city_model import CityModel
|
||||
from .user_model import UserModel
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
from cpl.application import StartupABC
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.database import DatabaseSettings
|
||||
from cpl.dependency import ServiceCollectionABC, ServiceProviderABC
|
||||
from cpl.core.environment import Environment
|
||||
from cpl.core.log import Logger, LoggerABC
|
||||
|
||||
from model.db_context import DBContext
|
||||
from cpl.database import mysql
|
||||
from cpl.dependency import ServiceCollection
|
||||
from model.user_repo import UserRepo
|
||||
from model.user_repo_abc import UserRepoABC
|
||||
|
||||
@@ -23,11 +21,8 @@ class Startup(StartupABC):
|
||||
|
||||
self._configuration = configuration
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, environment: Environment):
|
||||
# Create and connect to database
|
||||
db_settings: DatabaseSettings = self._configuration.get(DatabaseSettings)
|
||||
services.add_db_context(DBContext, db_settings)
|
||||
def configure_services(self, services: ServiceCollection, environment: Environment):
|
||||
services.add_module(mysql)
|
||||
|
||||
services.add_singleton(UserRepoABC, UserRepo)
|
||||
|
||||
services.add_singleton(LoggerABC, Logger)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from cpl.application import StartupABC
|
||||
from cpl.core.configuration import ConfigurationABC
|
||||
from cpl.dependency import ServiceProviderABC, ServiceCollectionABC
|
||||
from cpl.dependency import ServiceProviderABC, ServiceCollection
|
||||
from cpl.core.environment import Environment
|
||||
from di.test1_service import Test1Service
|
||||
from di.test2_service import Test2Service
|
||||
@@ -17,7 +17,7 @@ class Startup(StartupABC):
|
||||
def configure_configuration(self, configuration: ConfigurationABC, environment: Environment) -> ConfigurationABC:
|
||||
return configuration
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, environment: Environment) -> ServiceProviderABC:
|
||||
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
|
||||
services.add_scoped(TestService)
|
||||
services.add_scoped(DITesterService)
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from cpl import mail
|
||||
from cpl.application import StartupABC
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.dependency import ServiceCollectionABC, ServiceProviderABC
|
||||
from cpl.dependency import ServiceCollection, ServiceProviderABC
|
||||
from cpl.core.environment import Environment
|
||||
from cpl.core.pipes import IPAddressPipe
|
||||
from test_service import TestService
|
||||
@@ -15,8 +16,8 @@ class Startup(StartupABC):
|
||||
config.add_json_file(f"appsettings.{env.get_environment()}.json")
|
||||
config.add_json_file(f"appsettings.{env.get_host_name()}.json", optional=True)
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: Environment):
|
||||
def configure_services(self, services: ServiceCollection, env: Environment):
|
||||
services.add_logging()
|
||||
services.add_mail()
|
||||
services.add_module(mail)
|
||||
services.add_transient(IPAddressPipe)
|
||||
services.add_singleton(TestService)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from cpl.application import StartupExtensionABC
|
||||
from cpl.core.configuration import Configuration
|
||||
from cpl.core.console import Console
|
||||
from cpl.dependency import ServiceCollectionABC
|
||||
from cpl.dependency import ServiceCollection
|
||||
from cpl.core.environment import Environment
|
||||
|
||||
|
||||
@@ -12,5 +12,5 @@ class TestStartupExtension(StartupExtensionABC):
|
||||
def configure_configuration(self, config: Configuration, env: Environment):
|
||||
Console.write_line("config")
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, env: Environment):
|
||||
def configure_services(self, services: ServiceCollection, env: Environment):
|
||||
Console.write_line("services")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from cpl.application import StartupABC
|
||||
from cpl.core.configuration import ConfigurationABC
|
||||
from cpl.dependency import ServiceProviderABC, ServiceCollectionABC
|
||||
from cpl.dependency import ServiceProviderABC, ServiceCollection
|
||||
from cpl.core.environment import Environment
|
||||
|
||||
|
||||
@@ -12,6 +12,6 @@ class Startup(StartupABC):
|
||||
configuration.add_json_file("appsettings.json")
|
||||
return configuration
|
||||
|
||||
def configure_services(self, services: ServiceCollectionABC, environment: Environment) -> ServiceProviderABC:
|
||||
def configure_services(self, services: ServiceCollection, environment: Environment) -> ServiceProviderABC:
|
||||
services.add_translation()
|
||||
return services.build_service_provider()
|
||||
|
||||
Reference in New Issue
Block a user