<reponame>john-james-sf/predict-fda
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# =========================================================================== #
# Project  : Drug Approval Analytics                                          #
# Version  : 0.1.0                                                            #
# File     : \src\utils\config.py                                             #
# Language : Python 3.9.5                                                     #
# --------------------------------------------------------------------------  #
# Author   : <NAME>                                                       #
# Company  : nov8.ai                                                          #
# Email    : <EMAIL>                                               #
# URL      : https://github.com/john-james-sf/drug-approval-analytics         #
# --------------------------------------------------------------------------  #
# Created  : Thursday, July 15th 2021, 5:47:58 pm                             #
# Modified : Wednesday, August 18th 2021, 7:24:09 am                          #
# Modifier : <NAME> (<EMAIL>)                                  #
# --------------------------------------------------------------------------- #
# License  : BSD 3-clause "New" or "Revised" License                          #
# Copyright: (c) 2021 nov8.ai                                                 #
# =========================================================================== #
# %%
import os
from copy import copy, deepcopy
import logging
from configparser import ConfigParser
# --------------------------------------------------------------------------- #
logger = logging.getLogger(__name__)
# --------------------------------------------------------------------------- #


class Config:
    """Access object to the configuration file."""

    def __init__(self, filepath: str) -> None:
        self._filepath = filepath

    def _check_file(self, filepath):
        if not os.path.exists(filepath):
            logger.error("Configuration file {} not found.".format(filepath))
            raise FileNotFoundError

    def has_section(self, section):
        parser = ConfigParser()
        parser.read(self._filepath)
        return parser.has_section(str(section))

    def has_option(self, section, option):
        parser = ConfigParser()
        parser.read(self._filepath)
        return parser.has_option(str(section), str(option))

    def get_section(self, section: str) -> dict:
        """Returns section key-value pairs."""

        parser = ConfigParser()
        self._check_file(self._filepath)
        parser.read(self._filepath)

        config = {}
        try:
            params = parser.items(section)
        except Exception as e:
            logger.error(e)
            raise(e)

        for param in params:
            config[param[0]] = param[1]
        return config

    def set_section(self, section, params):
        """Sets or creates a section of parameters to config file."""

        parser = ConfigParser()
        parser.read(self._filepath)

        if not parser.has_section(str(section)):
            parser.add_section(str(section))
            parser[str(section)] = {}

        for option, value in params.items():
            parser[str(section)][str(option)] = str(value)

        with open(self._filepath, 'w+') as configfile:
            parser.write(configfile)

    def get_config(self, section, option):
        """Returns a configuration value given a section and option."""

        parser = ConfigParser()
        self._check_file(self._filepath)
        parser.read(self._filepath)

        try:
            config = parser.get(section, option)
        except Exception as e:
            logger.error(e)
            raise(e)

        return config

    def set_config(self, section, option, value):
        """Sets an existing configuration."""

        parser = ConfigParser()
        parser.read(self._filepath)

        if not parser.has_section(str(section)):
            parser.add_section(str(section))
            parser[str(section)] = {}

        parser[section][option] = value
        with open(self._filepath, 'w+') as configfile:
            parser.write(configfile)

    def delete_section(self, section: str):
        """Removes a section from the config file."""

        parser = ConfigParser()
        parser.read(self._filepath)
        parser.remove_section(section)
        with open(self._filepath, 'w+') as configfile:
            parser.write(configfile)

    @property
    def sections(self):
        """Returns a list of all sections in the configuration file."""
        parser = ConfigParser()
        parser.read(self._filepath)
        return parser.sections()

# --------------------------------------------------------------------------- #
#                     DATABASE CREDENTIALS READER                             #
# --------------------------------------------------------------------------- #


class DBCredentials:
    """Access object to for database credentials.

    Returns the database credentials for database having the dbname. Properties
    are exposed for credentials dictionary and for each variable
    independently.  The dictionary property is provided for
    database connection applications that accept credentials in
    a dictionary format.

    Arguments:
        filepath str: The path to the credentials configuration file.
    """

    filepath = 'config/database.cfg'

    def __init__(self, filepath: str = None) -> None:
        self._filepath = filepath if filepath is not None else \
            DBCredentials.filepath

    def keys(self):
        return list(self._credentials.keys())

    def __getitem__(self, key):
        return self._credentials[key]

    def create(self, user: str, password: str,
               host: str = 'localhost', dbname: str = 'rx2m',
               port: int = 5432) -> None:
        config = Config(self._filepath)
        section = self._format_section_name(user, dbname)
        params = {}
        params['user'] = user
        params['password'] = password
        params['host'] = host
        params['dbname'] = dbname
        params['port'] = port
        config.set_section(section=section, params=params)
        self._credentials = config.get_section(section=section)

    def read(self, user: str, dbname: str) -> dict:
        section = self._format_section_name(user, dbname)
        self.load(section)
        return self._credentials

    def delete(self, user: str, dbname: str) -> None:
        section = self._format_section_name(user, dbname)
        Config(self._filepath).delete_section(section)

    def get(self, user: str, dbname: str):
        section = self._format_section_name(user, dbname)
        self._credentials = Config(self._filepath).get_section(section)
        return self

    @property
    def dbname(self):
        return self._credentials['dbname']

    @property
    def host(self):
        return self._credentials['host']

    @property
    def user(self):
        return self._credentials['user']

    @property
    def password(self):
        return self._credentials['password']

    @property
    def port(self):
        return self._credentials['port']

    def _format_section_name(self, user: str, dbname: str):
        return user + "_" + dbname


# ----------------------------------------------------------------------------#
#                            DATA SOURCES                                     #
# ----------------------------------------------------------------------------#
class DataSourceConfig:
    """Access to data source configurations."""

    filepath = '../config/datasources.cfg'

    def __init__(self, filepath: str = None) -> None:
        self._filepath = filepath if filepath is not None \
            else DataSourceConfig.filepath

    def get_config(self, name: str) -> dict:
        sources = Config(self._filepath).get_config('data', 'sources')
        if name not in sources:
            raise Exception("{} is not a valid data source.".format(name))

        return Config(self._filepath).get_section(name)

    @property
    def datasources(self) -> list:
        sources = Config().get_config('data', 'sources')
        sources = sources.split(',')
        return sources


# ----------------------------------------------------------------------------#
#                           CONFIGURATIONS                                    #
# ----------------------------------------------------------------------------#
# Database credentials
pg_pg_login = DBCredentials().get('postgres', 'postgres')
pg_rx2m_login = DBCredentials().get('postgres', 'rx2m')
j2_pg_login = DBCredentials().get('j2', 'postgres')
j2_rx2m_login = DBCredentials().get('j2', 'rx2m')
aact_login = DBCredentials().get('postgres', 'AACT')


# %%

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# =========================================================================== #
# Project  : Drug Approval Analytics                                          #
# Version  : 0.1.0                                                            #
# File     : \src\utils\config.py                                             #
# Language : Python 3.9.5                                                     #
# --------------------------------------------------------------------------  #
# Author   : <NAME>                                                       #
# Company  : nov8.ai                                                          #
# Email    : <EMAIL>                                               #
# URL      : https://github.com/john-james-sf/drug-approval-analytics         #
# --------------------------------------------------------------------------  #
# Created  : Thursday, July 15th 2021, 5:47:58 pm                             #
# Modified : Wednesday, August 18th 2021, 7:24:09 am                          #
# Modifier : <NAME> (<EMAIL>)                                  #
# --------------------------------------------------------------------------- #
# License  : BSD 3-clause "New" or "Revised" License                          #
# Copyright: (c) 2021 nov8.ai                                                 #
# =========================================================================== #
# %%
import os
from copy import copy, deepcopy
import logging
from configparser import ConfigParser
# --------------------------------------------------------------------------- #
logger = logging.getLogger(__name__)
# --------------------------------------------------------------------------- #


class Config:
    """Access object to the configuration file."""

    def __init__(self, filepath: str) -> None:
        self._filepath = filepath

    def _check_file(self, filepath):
        if not os.path.exists(filepath):
            logger.error("Configuration file {} not found.".format(filepath))
            raise FileNotFoundError

    def has_section(self, section):
        parser = ConfigParser()
        parser.read(self._filepath)
        return parser.has_section(str(section))

    def has_option(self, section, option):
        parser = ConfigParser()
        parser.read(self._filepath)
        return parser.has_option(str(section), str(option))

    def get_section(self, section: str) -> dict:
        """Returns section key-value pairs."""

        parser = ConfigParser()
        self._check_file(self._filepath)
        parser.read(self._filepath)

        config = {}
        try:
            params = parser.items(section)
        except Exception as e:
            logger.error(e)
            raise(e)

        for param in params:
            config[param[0]] = param[1]
        return config

    def set_section(self, section, params):
        """Sets or creates a section of parameters to config file."""

        parser = ConfigParser()
        parser.read(self._filepath)

        if not parser.has_section(str(section)):
            parser.add_section(str(section))
            parser[str(section)] = {}

        for option, value in params.items():
            parser[str(section)][str(option)] = str(value)

        with open(self._filepath, 'w+') as configfile:
            parser.write(configfile)

    def get_config(self, section, option):
        """Returns a configuration value given a section and option."""

        parser = ConfigParser()
        self._check_file(self._filepath)
        parser.read(self._filepath)

        try:
            config = parser.get(section, option)
        except Exception as e:
            logger.error(e)
            raise(e)

        return config

    def set_config(self, section, option, value):
        """Sets an existing configuration."""

        parser = ConfigParser()
        parser.read(self._filepath)

        if not parser.has_section(str(section)):
            parser.add_section(str(section))
            parser[str(section)] = {}

        parser[section][option] = value
        with open(self._filepath, 'w+') as configfile:
            parser.write(configfile)

    def delete_section(self, section: str):
        """Removes a section from the config file."""

        parser = ConfigParser()
        parser.read(self._filepath)
        parser.remove_section(section)
        with open(self._filepath, 'w+') as configfile:
            parser.write(configfile)

    @property
    def sections(self):
        """Returns a list of all sections in the configuration file."""
        parser = ConfigParser()
        parser.read(self._filepath)
        return parser.sections()

# --------------------------------------------------------------------------- #
#                     DATABASE CREDENTIALS READER                             #
# --------------------------------------------------------------------------- #


class DBCredentials:
    """Access object to for database credentials.

    Returns the database credentials for database having the dbname. Properties
    are exposed for credentials dictionary and for each variable
    independently.  The dictionary property is provided for
    database connection applications that accept credentials in
    a dictionary format.

    Arguments:
        filepath str: The path to the credentials configuration file.
    """

    filepath = 'config/database.cfg'

    def __init__(self, filepath: str = None) -> None:
        self._filepath = filepath if filepath is not None else \
            DBCredentials.filepath

    def keys(self):
        return list(self._credentials.keys())

    def __getitem__(self, key):
        return self._credentials[key]

    def create(self, user: str, password: str,
               host: str = 'localhost', dbname: str = 'rx2m',
               port: int = 5432) -> None:
        config = Config(self._filepath)
        section = self._format_section_name(user, dbname)
        params = {}
        params['user'] = user
        params['password'] = password
        params['host'] = host
        params['dbname'] = dbname
        params['port'] = port
        config.set_section(section=section, params=params)
        self._credentials = config.get_section(section=section)

    def read(self, user: str, dbname: str) -> dict:
        section = self._format_section_name(user, dbname)
        self.load(section)
        return self._credentials

    def delete(self, user: str, dbname: str) -> None:
        section = self._format_section_name(user, dbname)
        Config(self._filepath).delete_section(section)

    def get(self, user: str, dbname: str):
        section = self._format_section_name(user, dbname)
        self._credentials = Config(self._filepath).get_section(section)
        return self

    @property
    def dbname(self):
        return self._credentials['dbname']

    @property
    def host(self):
        return self._credentials['host']

    @property
    def user(self):
        return self._credentials['user']

    @property
    def password(self):
        return self._credentials['password']

    @property
    def port(self):
        return self._credentials['port']

    def _format_section_name(self, user: str, dbname: str):
        return user + "_" + dbname


# ----------------------------------------------------------------------------#
#                            DATA SOURCES                                     #
# ----------------------------------------------------------------------------#
class DataSourceConfig:
    """Access to data source configurations."""

    filepath = '../config/datasources.cfg'

    def __init__(self, filepath: str = None) -> None:
        self._filepath = filepath if filepath is not None \
            else DataSourceConfig.filepath

    def get_config(self, name: str) -> dict:
        sources = Config(self._filepath).get_config('data', 'sources')
        if name not in sources:
            raise Exception("{} is not a valid data source.".format(name))

        return Config(self._filepath).get_section(name)

    @property
    def datasources(self) -> list:
        sources = Config().get_config('data', 'sources')
        sources = sources.split(',')
        return sources


# ----------------------------------------------------------------------------#
#                           CONFIGURATIONS                                    #
# ----------------------------------------------------------------------------#
# Database credentials
pg_pg_login = DBCredentials().get('postgres', 'postgres')
pg_rx2m_login = DBCredentials().get('postgres', 'rx2m')
j2_pg_login = DBCredentials().get('j2', 'postgres')
j2_rx2m_login = DBCredentials().get('j2', 'rx2m')
aact_login = DBCredentials().get('postgres', 'AACT')


# %%
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # =========================================================================== # # Project  : Drug Approval Analytics                                          # # Version  : 0.1.0                                                            # # File     : \src\utils\config.py                                             # # Language : Python 3.9.5                                                     # # --------------------------------------------------------------------------  # # Author   : <NAME>                                                       # # Company  : nov8.ai                                                          # # Email    : <EMAIL>                                               # # URL      : https://github.com/john-james-sf/drug-approval-analytics         # # --------------------------------------------------------------------------  # # Created  : Thursday, July 15th 2021, 5:47:58 pm                             # # Modified : Wednesday, August 18th 2021, 7:24:09 am                          # # Modifier : <NAME> (<EMAIL>)                                  # # --------------------------------------------------------------------------- # # License  : BSD 3-clause "New" or "Revised" License                          # # Copyright: (c) 2021 nov8.ai                                                 # # =========================================================================== # # %% # --------------------------------------------------------------------------- # # --------------------------------------------------------------------------- # Access object to the configuration file. Returns section key-value pairs. Sets or creates a section of parameters to config file. Returns a configuration value given a section and option. Sets an existing configuration. Removes a section from the config file. Returns a list of all sections in the configuration file. # --------------------------------------------------------------------------- # #                     DATABASE CREDENTIALS READER                             # # --------------------------------------------------------------------------- # Access object to for database credentials.      Returns the database credentials for database having the dbname. Properties     are exposed for credentials dictionary and for each variable     independently.  The dictionary property is provided for     database connection applications that accept credentials in     a dictionary format.      Arguments:         filepath str: The path to the credentials configuration file. # ----------------------------------------------------------------------------# #                            DATA SOURCES                                     # # ----------------------------------------------------------------------------# Access to data source configurations. # ----------------------------------------------------------------------------# #                           CONFIGURATIONS                                    # # ----------------------------------------------------------------------------# # Database credentials # %%