Source code for tradingmate.model.configuration

import json
import logging
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List

from ..utils import Utils

# FIXME Property should be of type JSON byt it requires typing to accepts recursive types
Property = Any
ConfigDict = Dict[str, Property]
CredentialDict = Dict[str, str]

DEFAULT_CREDENTIALS_PATH: Path = Path(
    Utils.get_install_path(), "config", ".credentials"
)


[docs]class ConfigurationManager: """ Class that loads the configuration and credentials files exposing methods to provide the configurable parameters """ config_filepath: Path config: ConfigDict credentials: CredentialDict def __init__(self, config_path: Path) -> None: self.config_filepath = config_path self.config = self._load_config() self.credentials = self._load_credentials() logging.info("ConfigurationManager initialised") def _load_config(self) -> ConfigDict: """ Load the configuration file """ with self.config_filepath.open(mode="r") as file: config = self._parse_raw_config(json.load(file)) return config def _load_credentials(self) -> CredentialDict: """ Load the credentials file """ if Path(self.get_credentials_path()).exists(): with Path(self.get_credentials_path()).open(mode="r") as f: return json.load(f) else: logging.warning( "Credentials not found: {}".format(str(self.get_credentials_path())) ) if DEFAULT_CREDENTIALS_PATH.exists(): with DEFAULT_CREDENTIALS_PATH.open(mode="r") as f: return json.load(f) else: logging.warning("Credentials not configured") return {"av_api_key": "unconfigured"} def _parse_raw_config(self, config_dict: ConfigDict) -> ConfigDict: config_copy = config_dict for key, value in config_copy.items(): if type(value) is dict: config_dict[key] = self._parse_raw_config(value) elif type(value) is list: for i in range(len(value)): config_dict[key][i] = ( self._replace_placeholders(config_dict[key][i]) if type(config_dict[key][i]) is str else config_dict[key][i] ) elif type(value) is str: config_dict[key] = self._replace_placeholders(config_dict[key]) return config_dict def _replace_placeholders(self, string: str) -> str: string = string.replace("{home}", str(Path.home())) string = string.replace( "{timestamp}", datetime.now().isoformat().replace(":", "_").replace(".", "_"), ) return string
[docs] def get_log_filepath(self) -> Path: """ Get the filepath of the log file """ filename = self._replace_placeholders("trading_mate_{timestamp}.log") return Path(Utils.get_install_path(), "log", filename)
[docs] def get_trading_database_path(self) -> List[Path]: """ Get the filepath of the trading log file """ return [Path(p) for p in self.config["trading_logs"]]
[docs] def get_credentials_path(self) -> Path: """ Get the filepath of the credentials file """ return Path(self.config["general"]["credentials_filepath"])
[docs] def get_polling_period(self) -> float: """ Get the application polling period """ return float(self.config["general"]["polling_period_sec"])
[docs] def get_configured_stocks_interface(self) -> str: """ Get the active configured stock interface """ return self.config["general"]["stocks_interface"]["active"]
[docs] def get_alpha_vantage_api_key(self) -> str: """ Get the alphavantage api key """ return self.credentials["av_api_key"]
[docs] def get_alpha_vantage_base_url(self) -> str: """ Get the alphavantage API base URI """ return self.config["alpha_vantage"]["api_base_uri"]
[docs] def get_alpha_vantage_polling_period(self) -> float: """ Get the alphavantage configured polling period """ return float(self.config["alpha_vantage"]["polling_period_sec"])
[docs] def get_yfinance_polling_period(self) -> float: """ Get the yfinance configured polling period """ return float(self.config["yfinance"]["polling_period_sec"])
[docs] def get_editable_config(self) -> ConfigDict: """ Get a dictionary containing the editable configuration parameters """ return self.config
[docs] def save_settings(self, config: ConfigDict) -> bool: """ Save the edited configuration settings """ # Overwrite settings and reload self.config = self._parse_raw_config(config) self.credentials = self._load_credentials() # Write into file the non-parsed config Utils.write_json_file(self.config_filepath, config) logging.info("ConfigurationManater - settings have been saved") return True