Skip to content

Module yajaw.configuration

Basic import statement for the module is:

from yajaw import configuration

Module description

Module responsible for handling the yajaw configuration.

YajawConfig

Class representing the configuration used by yajaw.

It defines a series of class attributes representing the configuration settings used by yajaw. It also provides the basic load and update configuration settings methods.

Attributes:

Name Type Description
JIRA_PAT str

Personal access token used to authenticate in Jira

JIRA_BASE_URL str

Base url serving the Jira instance

SERVER_API_V2 str

Path serving the rest server API version 2

SERVER_API str

Path serving the desired rest server API version

AGILE_API_V1 str

Path serving the rest agile API version 1

AGILE_API str

Path serving the rest agile API version 1

GREENHOPPER_API str

Path serving the internal rest greenhopper API

TRIES int

How many time a request will be attempted before it fails

DELAY float

Number of seconds to wait before submitting the next request

BACKOFF float

Number multiplied against the delay to define its new value in order to adjust the load against the Jira instance

LOGGER Logger

Logger instance created based on configuration settings

SEMAPHORE BoundedSemaphore

Semaphore object created based on configuration settings

TIMEOUT int

Number of seconds used to configure the semaphore timeout setting

DEFAULT_PAGINATION dict

Initial dictionary with the start position and number of results to be requested in paginated requests

Raises:

Type Description
NameError

Raised when it can't update the configuration using the provided section and settings.

Source code in yajaw/configuration.py
class YajawConfig:
    """
     Class representing the configuration used by yajaw.

    It defines a series of class attributes representing the
    configuration settings used by yajaw. It also provides
    the basic load and update configuration settings methods.

    Attributes:
        JIRA_PAT: Personal access token used to authenticate in Jira
        JIRA_BASE_URL: Base url serving the Jira instance
        SERVER_API_V2: Path serving the rest server API version 2
        SERVER_API: Path serving the desired rest server API version
        AGILE_API_V1: Path serving the rest agile API version 1
        AGILE_API: Path serving the rest agile API version 1
        GREENHOPPER_API: Path serving the internal rest greenhopper API
        TRIES: How many time a request will be attempted before it fails
        DELAY: Number of seconds to wait before submitting the next request
        BACKOFF: Number multiplied against the delay to define its new value\
        in order to adjust the load against the Jira instance
        LOGGER: Logger instance created based on configuration settings
        SEMAPHORE: Semaphore object created based on configuration settings
        TIMEOUT: Number of seconds used to configure the semaphore timeout setting
        DEFAULT_PAGINATION: Initial dictionary with the start position and number \
        of results to be requested in paginated requests

    Raises:
        NameError: Raised when it can't update the configuration\
        using the provided section and settings.
    """

    JIRA_PAT: str
    JIRA_BASE_URL: str
    SERVER_API_V2: str
    SERVER_API: str
    AGILE_API_V1: str
    AGILE_API: str
    GREENHOPPER_API: str
    TRIES: int
    DELAY: float
    BACKOFF: float
    LOGGER: logging.Logger
    SEMAPHORE: asyncio.BoundedSemaphore
    TIMEOUT: int
    DEFAULT_PAGINATION: dict

    _MIN_SEMAPHORE_LIMIT: int = 5

    _configuration_settings: ClassVar = {
        "jira": {
            "token": "AAA...",
            "base_url": "https://my-dummy-jira-url.com",
            "server_api_v2": "rest/api/2",
            "agile_api_v1": "rest/agile/1.0",
            "greenhopper_api": "rest/greenhopper/1.0",
        },
        "retries": {"tries": 10, "delay": 0.0, "backoff": 2},
        "requests": {"timeout": 60},
        "concurrency": {"semaphore_limit": 50},
        "pagination": {"page_results": 40},
    }

    __sections: ClassVar = ["jira", "log", "retries", "requests", "concurrency"]

    @staticmethod
    def configuration(
        section: str, setting: str
    ) -> str | float | dict | logging.Logger | asyncio.BoundedSemaphore:
        """
        Retrieves the specified configuration.

        Method returns the configuration setting for the provided
        section and setting

        Args:
            section (str): Section of the configuration.
            setting (str): Specific setting of the configuration under the section.

        Returns:
            Value of the configuration requested.
        """
        return YajawConfig._configuration_settings[section][setting]

    @staticmethod
    def update_configuration(
        section: str,
        setting: str,
        value: str | float | dict | logging.Logger | asyncio.BoundedSemaphore,
    ):
        """
        Update the provided configuration setting.

        Updates the configuration dictionary with the informed setting value
        using the section and setting keys and refresh the class attributes.

        Args:
            section (str): Section of the configuration.
            setting (str): Specific setting of the configuration under the section.\
            value (str | float | dict | logging.Logger | asyncio.BoundedSemaphore):\
            The setting value to be stored.

        Raises:
            NameError: Can't update the configuration using the provided section and settings.
        """
        if section in YajawConfig.__sections:
            YajawConfig._configuration_settings[section][setting] = value
            YajawConfig._set_class_variables()
        else:
            raise NameError

    @staticmethod
    def load_initial_settings():
        """
        Load settings from the configuration file.

        Yajaw settings are loaded to a dictionary in memory from a configuration file, or
        use default values if the file is missing. Jira instance and access must be updated
        if no file is found.
        """
        fname = "yajaw.toml"
        try:
            with open(Path.home() / ".yajaw" / fname, "rb") as toml:
                YajawConfig._configuration_settings = tomllib.load(toml)
        except FileNotFoundError:
            ...
        YajawConfig._configuration_settings["log"] = {}
        YajawConfig._configuration_settings["log"]["logger"] = YajawConfig._define_logger()
        limit = YajawConfig._configuration_settings["concurrency"]["semaphore_limit"]
        # Ensures da minimum value of 5 for the BoundedSemaphore
        semaphore_limit = (
            limit if limit > YajawConfig._MIN_SEMAPHORE_LIMIT else YajawConfig._MIN_SEMAPHORE_LIMIT
        )
        YajawConfig._configuration_settings["concurrency"]["semaphore"] = asyncio.BoundedSemaphore(
            semaphore_limit
        )
        YajawConfig._configuration_settings["pagination"]["default"] = {
            "startAt": 0,
            "maxResults": YajawConfig._configuration_settings["pagination"]["page_results"],
        }
        YajawConfig._set_class_variables()

    @staticmethod
    def _define_logger() -> logging.Logger:
        """
        Configures the logging.Logger used by yajaw.

        As a library, logger named 'yajaw' is set up but no additional configuration
        is made to display the messages. NullHandler adapter is set to this logger.
        Configure logging from the application. Extra parameter 'context_id' is set.

        Returns:
            The yajaw logging.Logger object.
        """

        logger = logging.getLogger("yajaw")
        logger.setLevel(logging.CRITICAL)
        ch = logging.NullHandler()
        logger.addHandler(ch)
        return logger

    @staticmethod
    def _set_class_variables():
        """
        Updates the class variablers with the setting from the dictionary.

        Yajaw settings are loaded to a dictionary in memory from a configuration file, or
        default values if the file is missing. The method takes the content from the
        dictionary and updates the class variables accordingly.
        """
        YajawConfig.JIRA_PAT = YajawConfig._configuration_settings["jira"]["token"]
        YajawConfig.JIRA_BASE_URL = YajawConfig._configuration_settings["jira"]["base_url"]
        YajawConfig.SERVER_API_V2 = YajawConfig._configuration_settings["jira"]["server_api_v2"]
        YajawConfig.SERVER_API = YajawConfig.SERVER_API_V2
        YajawConfig.AGILE_API_V1 = YajawConfig._configuration_settings["jira"]["agile_api_v1"]
        YajawConfig.AGILE_API = YajawConfig.AGILE_API_V1
        YajawConfig.GREENHOPPER_API = YajawConfig._configuration_settings["jira"]["greenhopper_api"]
        YajawConfig.TRIES = YajawConfig._configuration_settings["retries"]["tries"]
        YajawConfig.DELAY = YajawConfig._configuration_settings["retries"]["delay"]
        YajawConfig.BACKOFF = YajawConfig._configuration_settings["retries"]["backoff"]
        YajawConfig.LOGGER = YajawConfig._configuration_settings["log"]["logger"]
        YajawConfig.SEMAPHORE = YajawConfig._configuration_settings["concurrency"]["semaphore"]
        YajawConfig.TIMEOUT = YajawConfig._configuration_settings["requests"]["timeout"]
        YajawConfig.DEFAULT_PAGINATION = YajawConfig._configuration_settings["pagination"][
            "default"
        ]

configuration(section, setting) staticmethod

Retrieves the specified configuration.

Method returns the configuration setting for the provided section and setting

Parameters:

Name Type Description Default
section str

Section of the configuration.

required
setting str

Specific setting of the configuration under the section.

required

Returns:

Type Description
str | float | dict | Logger | BoundedSemaphore

Value of the configuration requested.

Source code in yajaw/configuration.py
@staticmethod
def configuration(
    section: str, setting: str
) -> str | float | dict | logging.Logger | asyncio.BoundedSemaphore:
    """
    Retrieves the specified configuration.

    Method returns the configuration setting for the provided
    section and setting

    Args:
        section (str): Section of the configuration.
        setting (str): Specific setting of the configuration under the section.

    Returns:
        Value of the configuration requested.
    """
    return YajawConfig._configuration_settings[section][setting]

load_initial_settings() staticmethod

Load settings from the configuration file.

Yajaw settings are loaded to a dictionary in memory from a configuration file, or use default values if the file is missing. Jira instance and access must be updated if no file is found.

Source code in yajaw/configuration.py
@staticmethod
def load_initial_settings():
    """
    Load settings from the configuration file.

    Yajaw settings are loaded to a dictionary in memory from a configuration file, or
    use default values if the file is missing. Jira instance and access must be updated
    if no file is found.
    """
    fname = "yajaw.toml"
    try:
        with open(Path.home() / ".yajaw" / fname, "rb") as toml:
            YajawConfig._configuration_settings = tomllib.load(toml)
    except FileNotFoundError:
        ...
    YajawConfig._configuration_settings["log"] = {}
    YajawConfig._configuration_settings["log"]["logger"] = YajawConfig._define_logger()
    limit = YajawConfig._configuration_settings["concurrency"]["semaphore_limit"]
    # Ensures da minimum value of 5 for the BoundedSemaphore
    semaphore_limit = (
        limit if limit > YajawConfig._MIN_SEMAPHORE_LIMIT else YajawConfig._MIN_SEMAPHORE_LIMIT
    )
    YajawConfig._configuration_settings["concurrency"]["semaphore"] = asyncio.BoundedSemaphore(
        semaphore_limit
    )
    YajawConfig._configuration_settings["pagination"]["default"] = {
        "startAt": 0,
        "maxResults": YajawConfig._configuration_settings["pagination"]["page_results"],
    }
    YajawConfig._set_class_variables()

update_configuration(section, setting, value) staticmethod

Update the provided configuration setting.

Updates the configuration dictionary with the informed setting value using the section and setting keys and refresh the class attributes.

Parameters:

Name Type Description Default
section str

Section of the configuration.

required
setting str

Specific setting of the configuration under the section. value (str | float | dict | logging.Logger | asyncio.BoundedSemaphore): The setting value to be stored.

required

Raises:

Type Description
NameError

Can't update the configuration using the provided section and settings.

Source code in yajaw/configuration.py
@staticmethod
def update_configuration(
    section: str,
    setting: str,
    value: str | float | dict | logging.Logger | asyncio.BoundedSemaphore,
):
    """
    Update the provided configuration setting.

    Updates the configuration dictionary with the informed setting value
    using the section and setting keys and refresh the class attributes.

    Args:
        section (str): Section of the configuration.
        setting (str): Specific setting of the configuration under the section.\
        value (str | float | dict | logging.Logger | asyncio.BoundedSemaphore):\
        The setting value to be stored.

    Raises:
        NameError: Can't update the configuration using the provided section and settings.
    """
    if section in YajawConfig.__sections:
        YajawConfig._configuration_settings[section][setting] = value
        YajawConfig._set_class_variables()
    else:
        raise NameError