extract_utils

 1import boto3, logging, json
 2from botocore.exceptions import ClientError
 3from decimal import Decimal
 4from typing import List, Dict, Any
 5from datetime import datetime
 6
 7
 8def get_secret(
 9    secret_name: str = "project-onyx/totesys-db-login", region_name: str = "eu-west-2"
10) -> Dict[str, Any]:
11    """
12    Retrieves a secret from AWS Secrets Manager and parses it as a dictionary.
13
14    :param secret_name: The name of the secret to retrieve.
15    :param region_name: The AWS region where the secret is stored.
16    :raises ClientError: If there is an error retrieving the secret.
17    :return: The secret as a dictionary.
18    """
19    # Create a Secrets Manager client
20    log_message(__name__, 10, "Entered get_secret")
21    try:
22        client = boto3.client(service_name="secretsmanager", region_name=region_name)
23        get_secret_value_response = client.get_secret_value(SecretId=secret_name)
24        secret = get_secret_value_response["SecretString"]
25        result_dict = json.loads(secret)
26        return result_dict
27
28    except ClientError as e:
29        # For a list of exceptions thrown, see
30        # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
31        log_message(__name__, "40", e.response["Error"]["Message"])
32        raise e
33
34
35def format_response(
36    columns: List[str], response: List[List[Any]]
37) -> List[Dict[str, Any]]:
38    """
39    Formats a response into a list of dictionaries with columns as keys.
40
41    Validates that each row in the response has the same number of elements as the columns.
42
43    :param columns: A list of column names.
44    :param response: A list of rows, where each row is a list of values.
45    :return: A list of dictionaries where each dictionary represents a row.
46    :raises ValueError: If any row in the response has a different number of elements than the columns.
47    """
48    log_message(__name__, 10, "Entered format_response")
49
50    formatted_response = []
51    num_columns = len(columns)
52
53    for row in response:
54        if len(row) != num_columns:
55            raise ValueError("Mismatch between number of columns and row length")
56
57        extracted_from_response = {}
58
59        for column, value in zip(columns, row):
60            if isinstance(value, datetime):
61                value = value.strftime("%Y-%m-%d %H:%M:%S")
62            elif isinstance(value, Decimal):
63                value = float(value)
64
65            extracted_from_response[column] = value
66
67        formatted_response.append(extracted_from_response)
68
69    return formatted_response
70
71
72def log_message(name: str, level: int, message: str = ""):
73    """
74    Sends a message to the logger at a specified level.
75
76    :param name: The name of the logger.
77    :param level: The logging level (one of 10, 20, 30, 40, 50).
78    :param message: The message to log.
79    """
80    logger = logging.getLogger(name)
81
82    # Define a mapping of level integers to logging methods
83    level_map = {
84        10: logger.debug,
85        20: logger.info,
86        30: logger.warning,
87        40: logger.error,
88        50: logger.critical,
89    }
90
91    # Get the logging method from the map
92    log_method = level_map.get(level)
93
94    if log_method:
95        log_method(message)
96    else:
97        logger.error("Invalid log level: %d", level)
def get_secret( secret_name: str = 'project-onyx/totesys-db-login', region_name: str = 'eu-west-2') -> Dict[str, Any]:
 9def get_secret(
10    secret_name: str = "project-onyx/totesys-db-login", region_name: str = "eu-west-2"
11) -> Dict[str, Any]:
12    """
13    Retrieves a secret from AWS Secrets Manager and parses it as a dictionary.
14
15    :param secret_name: The name of the secret to retrieve.
16    :param region_name: The AWS region where the secret is stored.
17    :raises ClientError: If there is an error retrieving the secret.
18    :return: The secret as a dictionary.
19    """
20    # Create a Secrets Manager client
21    log_message(__name__, 10, "Entered get_secret")
22    try:
23        client = boto3.client(service_name="secretsmanager", region_name=region_name)
24        get_secret_value_response = client.get_secret_value(SecretId=secret_name)
25        secret = get_secret_value_response["SecretString"]
26        result_dict = json.loads(secret)
27        return result_dict
28
29    except ClientError as e:
30        # For a list of exceptions thrown, see
31        # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html
32        log_message(__name__, "40", e.response["Error"]["Message"])
33        raise e

Retrieves a secret from AWS Secrets Manager and parses it as a dictionary.

Parameters
  • secret_name: The name of the secret to retrieve.
  • region_name: The AWS region where the secret is stored.
Raises
  • ClientError: If there is an error retrieving the secret.
Returns

The secret as a dictionary.

def format_response(columns: List[str], response: List[List[Any]]) -> List[Dict[str, Any]]:
36def format_response(
37    columns: List[str], response: List[List[Any]]
38) -> List[Dict[str, Any]]:
39    """
40    Formats a response into a list of dictionaries with columns as keys.
41
42    Validates that each row in the response has the same number of elements as the columns.
43
44    :param columns: A list of column names.
45    :param response: A list of rows, where each row is a list of values.
46    :return: A list of dictionaries where each dictionary represents a row.
47    :raises ValueError: If any row in the response has a different number of elements than the columns.
48    """
49    log_message(__name__, 10, "Entered format_response")
50
51    formatted_response = []
52    num_columns = len(columns)
53
54    for row in response:
55        if len(row) != num_columns:
56            raise ValueError("Mismatch between number of columns and row length")
57
58        extracted_from_response = {}
59
60        for column, value in zip(columns, row):
61            if isinstance(value, datetime):
62                value = value.strftime("%Y-%m-%d %H:%M:%S")
63            elif isinstance(value, Decimal):
64                value = float(value)
65
66            extracted_from_response[column] = value
67
68        formatted_response.append(extracted_from_response)
69
70    return formatted_response

Formats a response into a list of dictionaries with columns as keys.

Validates that each row in the response has the same number of elements as the columns.

Parameters
  • columns: A list of column names.
  • response: A list of rows, where each row is a list of values.
Returns

A list of dictionaries where each dictionary represents a row.

Raises
  • ValueError: If any row in the response has a different number of elements than the columns.
def log_message(name: str, level: int, message: str = ''):
73def log_message(name: str, level: int, message: str = ""):
74    """
75    Sends a message to the logger at a specified level.
76
77    :param name: The name of the logger.
78    :param level: The logging level (one of 10, 20, 30, 40, 50).
79    :param message: The message to log.
80    """
81    logger = logging.getLogger(name)
82
83    # Define a mapping of level integers to logging methods
84    level_map = {
85        10: logger.debug,
86        20: logger.info,
87        30: logger.warning,
88        40: logger.error,
89        50: logger.critical,
90    }
91
92    # Get the logging method from the map
93    log_method = level_map.get(level)
94
95    if log_method:
96        log_method(message)
97    else:
98        logger.error("Invalid log level: %d", level)

Sends a message to the logger at a specified level.

Parameters
  • name: The name of the logger.
  • level: The logging level (one of 10, 20, 30, 40, 50).
  • message: The message to log.