pycraftcore 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pycraftcore/__init__.py +0 -0
- pycraftcore/app_configuration/__init__.py +5 -0
- pycraftcore/app_configuration/adapter/__init__.py +0 -0
- pycraftcore/app_configuration/adapter/load_configuration.py +41 -0
- pycraftcore/app_configuration/adapter/omega_configuration_reader.py +52 -0
- pycraftcore/app_configuration/adapter/schema.py +29 -0
- pycraftcore/app_configuration/enum/__init__.py +0 -0
- pycraftcore/app_configuration/enum/connector_type.py +9 -0
- pycraftcore/app_configuration/enum/file_operation_action.py +7 -0
- pycraftcore/app_configuration/enum/run_type_application.py +6 -0
- pycraftcore/app_configuration/enum/run_type_environment.py +8 -0
- pycraftcore/app_configuration/model/__init__.py +0 -0
- pycraftcore/app_configuration/model/configuration.py +22 -0
- pycraftcore/app_configuration/model/connector.py +43 -0
- pycraftcore/app_configuration/model/cronjob.py +10 -0
- pycraftcore/app_configuration/model/operation.py +32 -0
- pycraftcore/app_configuration/port/__init__.py +0 -0
- pycraftcore/app_configuration/port/configuration.py +9 -0
- pycraftcore/app_configuration/port/configuration_reader.py +7 -0
- pycraftcore/authentication/__init__.py +5 -0
- pycraftcore/authentication/model/__init__.py +0 -0
- pycraftcore/authentication/model/auth_type.py +7 -0
- pycraftcore/authentication/model/basic_auth.py +10 -0
- pycraftcore/authentication/model/no_auth.py +8 -0
- pycraftcore/authentication/model/token_auth.py +10 -0
- pycraftcore/computation_engine/__init__.py +0 -0
- pycraftcore/computation_engine/adapter/__init__.py +0 -0
- pycraftcore/computation_engine/adapter/compute_engine.py +20 -0
- pycraftcore/computation_engine/adapter/numpy_arithmetic_operation.py +49 -0
- pycraftcore/computation_engine/adapter/scipy_calculus_operation.py +21 -0
- pycraftcore/computation_engine/const_typing.py +15 -0
- pycraftcore/computation_engine/port/__init__.py +0 -0
- pycraftcore/computation_engine/port/arithmetic_operation.py +15 -0
- pycraftcore/computation_engine/port/calculus_operation.py +11 -0
- pycraftcore/computation_engine/port/engine.py +16 -0
- pycraftcore/file_handler/__init__.py +0 -0
- pycraftcore/file_handler/adapter/__init__.py +0 -0
- pycraftcore/file_handler/adapter/extension/__init__.py +0 -0
- pycraftcore/file_handler/adapter/extension/yml_reader.py +12 -0
- pycraftcore/file_handler/adapter/extension/yml_writer.py +12 -0
- pycraftcore/file_handler/adapter/factory.py +37 -0
- pycraftcore/file_handler/adapter/handler.py +12 -0
- pycraftcore/file_handler/adapter/provider.py +10 -0
- pycraftcore/file_handler/adapter/strategy.py +23 -0
- pycraftcore/file_handler/port/__init__.py +0 -0
- pycraftcore/file_handler/port/reader.py +8 -0
- pycraftcore/file_handler/port/writer.py +8 -0
- pycraftcore/http/__init__.py +0 -0
- pycraftcore/http/adapter/__init__.py +15 -0
- pycraftcore/http/adapter/aiohttp_client.py +148 -0
- pycraftcore/http/adapter/circuit_breaker_policy.py +94 -0
- pycraftcore/http/adapter/httpx_client.py +210 -0
- pycraftcore/http/adapter/resilient_client.py +51 -0
- pycraftcore/http/adapter/retry_policy.py +50 -0
- pycraftcore/http/configuration/__init__.py +15 -0
- pycraftcore/http/configuration/circuite_breaker_configuration.py +8 -0
- pycraftcore/http/configuration/client_configuration.py +6 -0
- pycraftcore/http/configuration/http_client_configuration.py +16 -0
- pycraftcore/http/configuration/limits_configuration.py +11 -0
- pycraftcore/http/configuration/retry_configuration.py +13 -0
- pycraftcore/http/configuration/security_configuration.py +7 -0
- pycraftcore/http/context/__init__.py +0 -0
- pycraftcore/http/context/request_context.py +4 -0
- pycraftcore/http/enum/__init__.py +4 -0
- pycraftcore/http/enum/circuit_breaker_status.py +7 -0
- pycraftcore/http/enum/http_method.py +6 -0
- pycraftcore/http/exception/__init__.py +0 -0
- pycraftcore/http/exception/circuit_breaker_open_exception.py +1 -0
- pycraftcore/http/middleware/__init__.py +0 -0
- pycraftcore/http/middleware/request_id_middleware.py +25 -0
- pycraftcore/http/port/__init__.py +5 -0
- pycraftcore/http/port/async_circuit_breaker.py +18 -0
- pycraftcore/http/port/async_http_client.py +28 -0
- pycraftcore/http/port/async_resilient_http_client.py +8 -0
- pycraftcore/http/port/retry.py +12 -0
- pycraftcore/logger/__init__.py +0 -0
- pycraftcore/logger/adapter/__init__.py +0 -0
- pycraftcore/logger/adapter/loguru_logger.py +38 -0
- pycraftcore/logger/port/__init__.py +3 -0
- pycraftcore/logger/port/logger.py +15 -0
- pycraftcore/profiler/__init__.py +0 -0
- pycraftcore/profiler/profiled.py +20 -0
- pycraftcore/query_language/__init__.py +0 -0
- pycraftcore/query_language/constants/__init__.py +0 -0
- pycraftcore/query_language/constants/allowed_root_statements.py +9 -0
- pycraftcore/query_language/constants/forbidden_statements.py +17 -0
- pycraftcore/query_language/sql/__init__.py +0 -0
- pycraftcore/query_language/sql/adapter.py +40 -0
- pycraftcore/query_language/sql/factory.py +7 -0
- pycraftcore/query_language/sql/sql_handler.py +9 -0
- pycraftcore/repository/__init__.py +0 -0
- pycraftcore/repository/repository.py +17 -0
- pycraftcore/repository/sqlite/__init__.py +0 -0
- pycraftcore/repository/sqlite/adapter.py +36 -0
- pycraftcore/repository/sqlite/factory.py +70 -0
- pycraftcore/repository/sqlite/mapper.py +14 -0
- pycraftcore/repository/sqlite/schema.py +7 -0
- pycraftcore/runtime/__init__.py +0 -0
- pycraftcore/runtime/code.py +16 -0
- pycraftcore/runtime/python/__init__.py +0 -0
- pycraftcore/runtime/python/adapter.py +193 -0
- pycraftcore/runtime/python/factory.py +22 -0
- pycraftcore/runtime/python/schema.py +14 -0
- pycraftcore/serializer/__init__.py +0 -0
- pycraftcore/serializer/adapter/__init__.py +0 -0
- pycraftcore/serializer/adapter/binary_serializer.py +16 -0
- pycraftcore/serializer/adapter/dictionary_serializer.py +14 -0
- pycraftcore/serializer/adapter/json_serializer.py +15 -0
- pycraftcore/serializer/port/__init__.py +0 -0
- pycraftcore/serializer/port/serializer.py +11 -0
- pycraftcore/telemetry/__init__.py +3 -0
- pycraftcore/telemetry/adapter/__init__.py +0 -0
- pycraftcore/telemetry/adapter/open_telemetry.py +108 -0
- pycraftcore/telemetry/port/__init__.py +0 -0
- pycraftcore/telemetry/port/telemetry.py +15 -0
- pycraftcore-0.1.0.dist-info/METADATA +34 -0
- pycraftcore-0.1.0.dist-info/RECORD +120 -0
- pycraftcore-0.1.0.dist-info/WHEEL +5 -0
- pycraftcore-0.1.0.dist-info/licenses/LICENSE +21 -0
- pycraftcore-0.1.0.dist-info/top_level.txt +1 -0
pycraftcore/__init__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
from pycraftcore.app_configuration.model.configuration import AppConfiguration
|
|
2
|
+
from pycraftcore.app_configuration.port.configuration import Configuration
|
|
3
|
+
from pycraftcore.app_configuration.port.configuration_reader import ConfigurationReader
|
|
4
|
+
|
|
5
|
+
__all__ = ["AppConfiguration", "Configuration", "ConfigurationReader"]
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
from typing import ParamSpec
|
|
3
|
+
|
|
4
|
+
from pycraftcore.app_configuration.model.configuration import AppConfiguration
|
|
5
|
+
from pycraftcore.app_configuration.port.configuration_reader import (
|
|
6
|
+
ConfigurationReader,
|
|
7
|
+
)
|
|
8
|
+
from pycraftcore.logger.port.logger import Logger
|
|
9
|
+
|
|
10
|
+
P = ParamSpec("P")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class LoadConfiguration:
|
|
14
|
+
_instance = None
|
|
15
|
+
_lock = threading.Lock()
|
|
16
|
+
|
|
17
|
+
def __new__(cls, *args: P.args, **kwargs: P.kwargs):
|
|
18
|
+
if not cls._instance:
|
|
19
|
+
with cls._lock:
|
|
20
|
+
if not cls._instance:
|
|
21
|
+
cls._instance = object.__new__(cls)
|
|
22
|
+
return cls._instance
|
|
23
|
+
|
|
24
|
+
def __init__(self, configuration_reader: ConfigurationReader, logger: Logger):
|
|
25
|
+
self._configuration_reader = configuration_reader
|
|
26
|
+
self._logger = logger
|
|
27
|
+
self._cached_config: AppConfiguration | None = None
|
|
28
|
+
|
|
29
|
+
def load(self) -> AppConfiguration | None:
|
|
30
|
+
if self._cached_config is None:
|
|
31
|
+
try:
|
|
32
|
+
self._cached_config = self._configuration_reader.read()
|
|
33
|
+
except Exception as exception:
|
|
34
|
+
self._logger.critical(exception.__str__())
|
|
35
|
+
return self._cached_config
|
|
36
|
+
|
|
37
|
+
def reload(self) -> AppConfiguration | None:
|
|
38
|
+
with self._lock:
|
|
39
|
+
configuration = self._configuration_reader.read()
|
|
40
|
+
self._cached_config = configuration
|
|
41
|
+
return self._cached_config
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import cast, Any
|
|
3
|
+
|
|
4
|
+
from omegaconf import OmegaConf, DictConfig
|
|
5
|
+
|
|
6
|
+
from pycraftcore.app_configuration.adapter.schema import (
|
|
7
|
+
AppConfigurationSchema,
|
|
8
|
+
MapperDomainSchema,
|
|
9
|
+
)
|
|
10
|
+
from pycraftcore.app_configuration.enum.run_type_environment import (
|
|
11
|
+
RunTypeEnvironment,
|
|
12
|
+
)
|
|
13
|
+
from pycraftcore.app_configuration.model.configuration import AppConfiguration
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class OmegaConfigurationReader:
|
|
17
|
+
FILE_EXTENSION = "yml"
|
|
18
|
+
ROOT_CONFIG_FILE_NAME = "root"
|
|
19
|
+
CONNECTOR_CONFIG_FILE_NAME = "connector"
|
|
20
|
+
OPERATION_CONFIG_FILE_NAME = "operation"
|
|
21
|
+
CRONJOB_CONFIG_FILE_NAME = "cronjob"
|
|
22
|
+
|
|
23
|
+
def __init__(self, env: RunTypeEnvironment, config_directory: Path) -> None:
|
|
24
|
+
self._env = env
|
|
25
|
+
self._config_directory = config_directory
|
|
26
|
+
|
|
27
|
+
def read(self) -> AppConfiguration:
|
|
28
|
+
config_root: Path = (
|
|
29
|
+
self._config_directory / f"{self.ROOT_CONFIG_FILE_NAME}.{self.FILE_EXTENSION}"
|
|
30
|
+
)
|
|
31
|
+
config_dir_env = self._config_directory / f"{self._env.value}"
|
|
32
|
+
|
|
33
|
+
omega_config: DictConfig = self._omega_read(config_dir_env, config_root)
|
|
34
|
+
omega_container: Any = OmegaConf.to_container(
|
|
35
|
+
omega_config.app_configuration, resolve=True, throw_on_missing=True
|
|
36
|
+
)
|
|
37
|
+
app_config_schema = AppConfigurationSchema(**omega_container)
|
|
38
|
+
return MapperDomainSchema.map(app_config_schema)
|
|
39
|
+
|
|
40
|
+
def _omega_read(self, config_dir_env: Path, config_root: Path) -> DictConfig:
|
|
41
|
+
return cast(
|
|
42
|
+
DictConfig,
|
|
43
|
+
OmegaConf.merge(
|
|
44
|
+
*self._load_yml_dir(config_dir_env / self.CONNECTOR_CONFIG_FILE_NAME),
|
|
45
|
+
*self._load_yml_dir(config_dir_env / self.OPERATION_CONFIG_FILE_NAME),
|
|
46
|
+
*self._load_yml_dir(config_dir_env / self.CRONJOB_CONFIG_FILE_NAME),
|
|
47
|
+
OmegaConf.load(config_root),
|
|
48
|
+
),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
def _load_yml_dir(self, directory: Path) -> list:
|
|
52
|
+
return [OmegaConf.load(f) for f in sorted(directory.glob(f"*.{self.FILE_EXTENSION}"))]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from pydantic import BaseModel
|
|
2
|
+
from typing import Sequence
|
|
3
|
+
|
|
4
|
+
from pycraftcore.app_configuration.enum.connector_type import ConnectorType
|
|
5
|
+
from pycraftcore.app_configuration.enum.run_type_application import (
|
|
6
|
+
RunTypeApplication,
|
|
7
|
+
)
|
|
8
|
+
from pycraftcore.app_configuration.enum.run_type_environment import (
|
|
9
|
+
RunTypeEnvironment,
|
|
10
|
+
)
|
|
11
|
+
from pycraftcore.app_configuration.model.configuration import AppConfiguration
|
|
12
|
+
from pycraftcore.app_configuration.model.connector import ConnectorTyping
|
|
13
|
+
|
|
14
|
+
from pycraftcore.app_configuration.model.cronjob import CronJob
|
|
15
|
+
from pycraftcore.app_configuration.model.operation import OperationTyping
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
class AppConfigurationSchema(BaseModel):
|
|
19
|
+
env: RunTypeEnvironment
|
|
20
|
+
run: RunTypeApplication
|
|
21
|
+
connector: dict[ConnectorType, dict[str, ConnectorTyping]]
|
|
22
|
+
operation: dict[str, OperationTyping]
|
|
23
|
+
cronjob: Sequence[CronJob]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class MapperDomainSchema:
|
|
27
|
+
@staticmethod
|
|
28
|
+
def map(app_configuration_schema: AppConfigurationSchema) -> AppConfiguration:
|
|
29
|
+
return AppConfiguration(**vars(app_configuration_schema))
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from typing import Sequence
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
|
|
4
|
+
from pycraftcore.app_configuration.enum.connector_type import ConnectorType
|
|
5
|
+
from pycraftcore.app_configuration.enum.run_type_application import (
|
|
6
|
+
RunTypeApplication,
|
|
7
|
+
)
|
|
8
|
+
from pycraftcore.app_configuration.enum.run_type_environment import (
|
|
9
|
+
RunTypeEnvironment,
|
|
10
|
+
)
|
|
11
|
+
from pycraftcore.app_configuration.model.connector import ConnectorTyping
|
|
12
|
+
from pycraftcore.app_configuration.model.cronjob import CronJob
|
|
13
|
+
from pycraftcore.app_configuration.model.operation import OperationTyping
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True)
|
|
17
|
+
class AppConfiguration:
|
|
18
|
+
env: RunTypeEnvironment
|
|
19
|
+
run: RunTypeApplication
|
|
20
|
+
connector: dict[ConnectorType, dict[str, ConnectorTyping]]
|
|
21
|
+
operation: dict[str, OperationTyping]
|
|
22
|
+
cronjob: Sequence[CronJob]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from typing import Union
|
|
3
|
+
|
|
4
|
+
from pycraftcore.app_configuration.enum.connector_type import ConnectorType
|
|
5
|
+
from pycraftcore.authentication import AuthTyping
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@dataclass(slots=True)
|
|
9
|
+
class BaseConnector:
|
|
10
|
+
name: str
|
|
11
|
+
type: ConnectorType
|
|
12
|
+
auth: AuthTyping
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(slots=True)
|
|
16
|
+
class ApiConnector(BaseConnector):
|
|
17
|
+
base_url: str
|
|
18
|
+
timeout: int
|
|
19
|
+
retry: int
|
|
20
|
+
certificate: str | None = field(default=None)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(slots=True)
|
|
24
|
+
class DatabaseConnector(BaseConnector):
|
|
25
|
+
engine: str
|
|
26
|
+
host: str
|
|
27
|
+
port: int
|
|
28
|
+
default_name: str
|
|
29
|
+
pool: dict[str, int]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@dataclass(slots=True)
|
|
33
|
+
class FileConnector(BaseConnector):
|
|
34
|
+
base_path: str
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass(slots=True)
|
|
38
|
+
class TelemetryConnector(BaseConnector):
|
|
39
|
+
host: str
|
|
40
|
+
port: int
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
ConnectorTyping = Union[ApiConnector, FileConnector, DatabaseConnector, TelemetryConnector]
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Union, List
|
|
3
|
+
|
|
4
|
+
from pycraftcore.app_configuration.enum.file_operation_action import (
|
|
5
|
+
FileOperationAction,
|
|
6
|
+
)
|
|
7
|
+
from pycraftcore.app_configuration.model.connector import ConnectorTyping
|
|
8
|
+
from pycraftcore.http.enum.http_method import HttpMethod
|
|
9
|
+
|
|
10
|
+
ParamType = Union[str, List[str]]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass(slots=True)
|
|
14
|
+
class BaseOperation:
|
|
15
|
+
name: str
|
|
16
|
+
connector: ConnectorTyping
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass(slots=True)
|
|
20
|
+
class ApiOperation(BaseOperation):
|
|
21
|
+
endpoint: str
|
|
22
|
+
method: HttpMethod
|
|
23
|
+
parameters: dict[str, ParamType]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(slots=True)
|
|
27
|
+
class FileOperation(BaseOperation):
|
|
28
|
+
action: FileOperationAction
|
|
29
|
+
parameters: dict[str, ParamType]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
OperationTyping = Union[FileOperation, ApiOperation]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from pycraftcore.computation_engine.port.arithmetic_operation import (
|
|
2
|
+
ArithmeticOperation,
|
|
3
|
+
)
|
|
4
|
+
from pycraftcore.computation_engine.port.calculus_operation import (
|
|
5
|
+
CalculusOperation,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ComputeEngine:
|
|
10
|
+
def __init__(self, arithmetic: ArithmeticOperation, calculus: CalculusOperation):
|
|
11
|
+
self._arithmetic = arithmetic
|
|
12
|
+
self._calculus = calculus
|
|
13
|
+
|
|
14
|
+
@property
|
|
15
|
+
def arithmetic(self) -> ArithmeticOperation:
|
|
16
|
+
return self._arithmetic
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def calculus(self) -> CalculusOperation:
|
|
20
|
+
return self._calculus
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from typing import Sequence, Any
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from pycraftcore.computation_engine.const_typing import Numeric
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class NumPyArithmeticOperation:
|
|
9
|
+
def to_array(self, sequence: Sequence[Any]) -> np.ndarray:
|
|
10
|
+
return self._as_array(sequence)
|
|
11
|
+
|
|
12
|
+
def log_returns(self, sequence: Sequence[Numeric]) -> np.ndarray:
|
|
13
|
+
|
|
14
|
+
if len(sequence) < 2:
|
|
15
|
+
return self._empty_array()
|
|
16
|
+
|
|
17
|
+
array = self._as_array(sequence)
|
|
18
|
+
|
|
19
|
+
ratio = array[1:] / array[:-1]
|
|
20
|
+
ratio = np.where(ratio <= 0, np.nan, ratio)
|
|
21
|
+
return np.log(ratio)
|
|
22
|
+
|
|
23
|
+
def rolling_average(self, sequence: Sequence[Numeric], window: int = 5) -> np.ndarray:
|
|
24
|
+
if len(sequence) < window:
|
|
25
|
+
return self._empty_array()
|
|
26
|
+
|
|
27
|
+
array = self._as_array(sequence)
|
|
28
|
+
kernel = self._as_array((np.ones(window) / window).astype(np.float64))
|
|
29
|
+
return np.convolve(array, kernel)
|
|
30
|
+
|
|
31
|
+
def rolling_standard_deviation(
|
|
32
|
+
self, sequence: Sequence[Numeric], window: int = 5
|
|
33
|
+
) -> np.ndarray:
|
|
34
|
+
if len(sequence) < window:
|
|
35
|
+
return self._empty_array()
|
|
36
|
+
|
|
37
|
+
array = self._as_array(sequence)
|
|
38
|
+
|
|
39
|
+
return np.array([np.std(array[i : i + window]) for i in range(len(array) - window + 1)])
|
|
40
|
+
|
|
41
|
+
@staticmethod
|
|
42
|
+
def _empty_array() -> np.ndarray:
|
|
43
|
+
return np.array([], dtype=np.float64)
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def _as_array(sequence: Sequence[Any]) -> np.ndarray:
|
|
47
|
+
if isinstance(sequence, np.ndarray):
|
|
48
|
+
return sequence
|
|
49
|
+
return np.asarray(sequence, dtype=np.float64)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from typing import Sequence, Any
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from scipy import interpolate, integrate
|
|
5
|
+
|
|
6
|
+
from pycraftcore.computation_engine.const_typing import Numeric, Kind
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class ScipyCalculusOperation:
|
|
10
|
+
def _to_array(self, sequence: Sequence[Any]) -> np.ndarray:
|
|
11
|
+
return np.asarray(sequence, dtype=np.float64)
|
|
12
|
+
|
|
13
|
+
def integrate(self, sequence: Sequence[Numeric], dx: float) -> float:
|
|
14
|
+
arr = self._to_array(sequence)
|
|
15
|
+
return float(integrate.trapezoid(arr, dx=dx))
|
|
16
|
+
|
|
17
|
+
def interpolate(self, sequence: Sequence[Numeric], kind: Kind = "linear") -> Sequence[Numeric]:
|
|
18
|
+
arr = self._to_array(sequence)
|
|
19
|
+
x = np.arange(len(arr))
|
|
20
|
+
f = interpolate.interp1d(x, arr, kind=kind)
|
|
21
|
+
return f(x)
|
|
File without changes
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from typing import Sequence, Any, Protocol
|
|
2
|
+
|
|
3
|
+
from pycraftcore.computation_engine.const_typing import Numeric
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ArithmeticOperation(Protocol):
|
|
7
|
+
def to_array(self, sequence: Sequence[Any]) -> Sequence[Any]: ...
|
|
8
|
+
|
|
9
|
+
def log_returns(self, sequence: Sequence[Numeric]) -> Sequence[Numeric]: ...
|
|
10
|
+
|
|
11
|
+
def rolling_average(self, sequence: Sequence[Numeric], window: int) -> Sequence[Numeric]: ...
|
|
12
|
+
|
|
13
|
+
def rolling_standard_deviation(
|
|
14
|
+
self, sequence: Sequence[Numeric], window: int
|
|
15
|
+
) -> Sequence[Numeric]: ...
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Sequence, Protocol
|
|
2
|
+
|
|
3
|
+
from pycraftcore.computation_engine.const_typing import Numeric, Kind
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class CalculusOperation(Protocol):
|
|
7
|
+
def integrate(self, sequence: Sequence[Numeric], dx: float) -> float: ...
|
|
8
|
+
|
|
9
|
+
def interpolate(
|
|
10
|
+
self, sequence: Sequence[Numeric], kind: Kind = "linear"
|
|
11
|
+
) -> Sequence[Numeric]: ...
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from typing import Protocol
|
|
2
|
+
|
|
3
|
+
from pycraftcore.computation_engine.port.arithmetic_operation import (
|
|
4
|
+
ArithmeticOperation,
|
|
5
|
+
)
|
|
6
|
+
from pycraftcore.computation_engine.port.calculus_operation import (
|
|
7
|
+
CalculusOperation,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class Engine(Protocol):
|
|
12
|
+
@property
|
|
13
|
+
def arithmetic(self) -> ArithmeticOperation: ...
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def calculus(self) -> CalculusOperation: ...
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import yaml
|
|
4
|
+
|
|
5
|
+
from pycraftcore.file_handler.port.reader import Reader
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class YmlFileReader(Reader):
|
|
9
|
+
@staticmethod
|
|
10
|
+
def read(file_path: str) -> dict[str, Any]:
|
|
11
|
+
with open(file_path, "r") as file:
|
|
12
|
+
return yaml.safe_load(file)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import yaml
|
|
4
|
+
|
|
5
|
+
from pycraftcore.file_handler.port.writer import Writer
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class YmlFileWriter(Writer):
|
|
9
|
+
@staticmethod
|
|
10
|
+
def write(file_path: str, data: dict[str, Any]) -> None:
|
|
11
|
+
with open(file_path, "w") as file:
|
|
12
|
+
yaml.dump(data, file)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pycraftcore.file_handler.adapter.strategy import FileHandlerStrategy
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FileHandlerFactory:
|
|
8
|
+
def __init__(self, file_path: str, strategy: FileHandlerStrategy) -> None:
|
|
9
|
+
self._file_path = Path(file_path)
|
|
10
|
+
self._strategy = strategy
|
|
11
|
+
|
|
12
|
+
def _file_extension(self) -> str:
|
|
13
|
+
return self._file_path.suffix.lstrip(".")
|
|
14
|
+
|
|
15
|
+
def _validate_file_for_read(self) -> None:
|
|
16
|
+
if not self._file_path.exists():
|
|
17
|
+
raise FileNotFoundError(f"File not found at {self._file_path}")
|
|
18
|
+
|
|
19
|
+
if not self._strategy.supports(self._file_extension()):
|
|
20
|
+
raise NotImplementedError(f"File extension not supported: {self._file_extension()}")
|
|
21
|
+
|
|
22
|
+
def _validate_file_for_write(self) -> None:
|
|
23
|
+
if not self._file_path.parent.exists():
|
|
24
|
+
raise FileNotFoundError(f"File location not found at {self._file_path}")
|
|
25
|
+
|
|
26
|
+
if not self._strategy.supports(self._file_extension()):
|
|
27
|
+
raise NotImplementedError(f"File extension not supported: {self._file_extension()}")
|
|
28
|
+
|
|
29
|
+
def read(self) -> dict[str, Any]:
|
|
30
|
+
self._validate_file_for_read()
|
|
31
|
+
reader = self._strategy.get_reader(self._file_extension())
|
|
32
|
+
return reader.read(str(self._file_path))
|
|
33
|
+
|
|
34
|
+
def write(self, data: Any) -> None:
|
|
35
|
+
self._validate_file_for_write()
|
|
36
|
+
writer = self._strategy.get_writer(self._file_extension())
|
|
37
|
+
writer.write(str(self._file_path), data)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from pycraftcore.file_handler.adapter.provider import FileHandlerProvider
|
|
2
|
+
from pycraftcore.file_handler.adapter.strategy import FileHandlerStrategy
|
|
3
|
+
from pycraftcore.file_handler.adapter.extension.yml_reader import YmlFileReader
|
|
4
|
+
from pycraftcore.file_handler.adapter.extension.yml_writer import YmlFileWriter
|
|
5
|
+
|
|
6
|
+
strategy = FileHandlerStrategy(
|
|
7
|
+
{
|
|
8
|
+
"yml": {"reader": YmlFileReader(), "writer": YmlFileWriter()},
|
|
9
|
+
}
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
Handler = FileHandlerProvider(strategy)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
from pycraftcore.file_handler.adapter.factory import FileHandlerFactory
|
|
2
|
+
from pycraftcore.file_handler.adapter.strategy import FileHandlerStrategy
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class FileHandlerProvider:
|
|
6
|
+
def __init__(self, strategy: FileHandlerStrategy) -> None:
|
|
7
|
+
self._strategy = strategy
|
|
8
|
+
|
|
9
|
+
def __call__(self, file_path: str) -> FileHandlerFactory:
|
|
10
|
+
return FileHandlerFactory(file_path, self._strategy)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from typing import TypedDict
|
|
2
|
+
|
|
3
|
+
from pycraftcore.file_handler.port.reader import Reader
|
|
4
|
+
from pycraftcore.file_handler.port.writer import Writer
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class FileHandlerDict(TypedDict):
|
|
8
|
+
reader: Reader
|
|
9
|
+
writer: Writer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class FileHandlerStrategy:
|
|
13
|
+
def __init__(self, handlers: dict[str, FileHandlerDict]) -> None:
|
|
14
|
+
self._handlers = handlers
|
|
15
|
+
|
|
16
|
+
def get_reader(self, extension: str) -> Reader:
|
|
17
|
+
return self._handlers[extension]["reader"]
|
|
18
|
+
|
|
19
|
+
def get_writer(self, extension: str) -> Writer:
|
|
20
|
+
return self._handlers[extension]["writer"]
|
|
21
|
+
|
|
22
|
+
def supports(self, extension: str) -> bool:
|
|
23
|
+
return extension in self._handlers
|
|
File without changes
|