Module aws_lambda_powertools.utilities.feature_flags.appconfig
Expand source code
import logging
import traceback
from typing import Any, Dict, Optional, Union, cast
from botocore.config import Config
from aws_lambda_powertools.utilities import jmespath_utils
from aws_lambda_powertools.utilities.parameters import (
AppConfigProvider,
GetParameterError,
TransformParameterError,
)
from ... import Logger
from .base import StoreProvider
from .exceptions import ConfigurationStoreError, StoreClientError
class AppConfigStore(StoreProvider):
def __init__(
self,
environment: str,
application: str,
name: str,
max_age: int = 5,
sdk_config: Optional[Config] = None,
envelope: Optional[str] = "",
jmespath_options: Optional[Dict] = None,
logger: Optional[Union[logging.Logger, Logger]] = None,
):
"""This class fetches JSON schemas from AWS AppConfig
Parameters
----------
environment: str
Appconfig environment, e.g. 'dev/test' etc.
application: str
AppConfig application name, e.g. 'powertools'
name: str
AppConfig configuration name e.g. `my_conf`
max_age: int
cache expiration time in seconds, or how often to call AppConfig to fetch latest configuration
sdk_config: Optional[Config]
Botocore Config object to pass during client initialization
envelope : Optional[str]
JMESPath expression to pluck feature flags data from config
jmespath_options : Optional[Dict]
Alternative JMESPath options to be included when filtering expr
logger: A logging object
Used to log messages. If None is supplied, one will be created.
"""
super().__init__()
self.logger = logger or logging.getLogger(__name__)
self.environment = environment
self.application = application
self.name = name
self.cache_seconds = max_age
self.config = sdk_config
self.envelope = envelope
self.jmespath_options = jmespath_options
self._conf_store = AppConfigProvider(environment=environment, application=application, config=sdk_config)
@property
def get_raw_configuration(self) -> Dict[str, Any]:
"""Fetch feature schema configuration from AWS AppConfig"""
try:
# parse result conf as JSON, keep in cache for self.max_age seconds
self.logger.debug(
"Fetching configuration from the store", extra={"param_name": self.name, "max_age": self.cache_seconds}
)
return cast(
dict,
self._conf_store.get(
name=self.name,
transform="json",
max_age=self.cache_seconds,
),
)
except (GetParameterError, TransformParameterError) as exc:
err_msg = traceback.format_exc()
if "AccessDenied" in err_msg:
raise StoreClientError(err_msg) from exc
raise ConfigurationStoreError("Unable to get AWS AppConfig configuration file") from exc
def get_configuration(self) -> Dict[str, Any]:
"""Fetch feature schema configuration from AWS AppConfig
If envelope is set, it'll extract and return feature flags from configuration,
otherwise it'll return the entire configuration fetched from AWS AppConfig.
Raises
------
ConfigurationStoreError
Any validation error or AppConfig error that can occur
Returns
-------
Dict[str, Any]
parsed JSON dictionary
"""
config = self.get_raw_configuration
if self.envelope:
self.logger.debug("Envelope enabled; extracting data from config", extra={"envelope": self.envelope})
config = jmespath_utils.extract_data_from_envelope(
data=config, envelope=self.envelope, jmespath_options=self.jmespath_options
)
return config
Classes
class AppConfigStore (environment: str, application: str, name: str, max_age: int = 5, sdk_config: Optional[botocore.config.Config] = None, envelope: Optional[str] = '', jmespath_options: Optional[Dict[~KT, ~VT]] = None, logger: Union[logging.Logger, Logger, None] = None)
-
Helper class that provides a standard way to create an ABC using inheritance.
This class fetches JSON schemas from AWS AppConfig
Parameters
environment
:str
- Appconfig environment, e.g. 'dev/test' etc.
application
:str
- AppConfig application name, e.g. 'powertools'
name
:str
- AppConfig configuration name e.g.
my_conf
max_age
:int
- cache expiration time in seconds, or how often to call AppConfig to fetch latest configuration
sdk_config
:Optional[Config]
- Botocore Config object to pass during client initialization
envelope
:Optional[str]
- JMESPath expression to pluck feature flags data from config
jmespath_options
:Optional[Dict]
- Alternative JMESPath options to be included when filtering expr
logger
:A logging object
- Used to log messages. If None is supplied, one will be created.
Expand source code
class AppConfigStore(StoreProvider): def __init__( self, environment: str, application: str, name: str, max_age: int = 5, sdk_config: Optional[Config] = None, envelope: Optional[str] = "", jmespath_options: Optional[Dict] = None, logger: Optional[Union[logging.Logger, Logger]] = None, ): """This class fetches JSON schemas from AWS AppConfig Parameters ---------- environment: str Appconfig environment, e.g. 'dev/test' etc. application: str AppConfig application name, e.g. 'powertools' name: str AppConfig configuration name e.g. `my_conf` max_age: int cache expiration time in seconds, or how often to call AppConfig to fetch latest configuration sdk_config: Optional[Config] Botocore Config object to pass during client initialization envelope : Optional[str] JMESPath expression to pluck feature flags data from config jmespath_options : Optional[Dict] Alternative JMESPath options to be included when filtering expr logger: A logging object Used to log messages. If None is supplied, one will be created. """ super().__init__() self.logger = logger or logging.getLogger(__name__) self.environment = environment self.application = application self.name = name self.cache_seconds = max_age self.config = sdk_config self.envelope = envelope self.jmespath_options = jmespath_options self._conf_store = AppConfigProvider(environment=environment, application=application, config=sdk_config) @property def get_raw_configuration(self) -> Dict[str, Any]: """Fetch feature schema configuration from AWS AppConfig""" try: # parse result conf as JSON, keep in cache for self.max_age seconds self.logger.debug( "Fetching configuration from the store", extra={"param_name": self.name, "max_age": self.cache_seconds} ) return cast( dict, self._conf_store.get( name=self.name, transform="json", max_age=self.cache_seconds, ), ) except (GetParameterError, TransformParameterError) as exc: err_msg = traceback.format_exc() if "AccessDenied" in err_msg: raise StoreClientError(err_msg) from exc raise ConfigurationStoreError("Unable to get AWS AppConfig configuration file") from exc def get_configuration(self) -> Dict[str, Any]: """Fetch feature schema configuration from AWS AppConfig If envelope is set, it'll extract and return feature flags from configuration, otherwise it'll return the entire configuration fetched from AWS AppConfig. Raises ------ ConfigurationStoreError Any validation error or AppConfig error that can occur Returns ------- Dict[str, Any] parsed JSON dictionary """ config = self.get_raw_configuration if self.envelope: self.logger.debug("Envelope enabled; extracting data from config", extra={"envelope": self.envelope}) config = jmespath_utils.extract_data_from_envelope( data=config, envelope=self.envelope, jmespath_options=self.jmespath_options ) return config
Ancestors
- StoreProvider
- abc.ABC
Instance variables
var get_raw_configuration : Dict[str, Any]
-
Fetch feature schema configuration from AWS AppConfig
Expand source code
@property def get_raw_configuration(self) -> Dict[str, Any]: """Fetch feature schema configuration from AWS AppConfig""" try: # parse result conf as JSON, keep in cache for self.max_age seconds self.logger.debug( "Fetching configuration from the store", extra={"param_name": self.name, "max_age": self.cache_seconds} ) return cast( dict, self._conf_store.get( name=self.name, transform="json", max_age=self.cache_seconds, ), ) except (GetParameterError, TransformParameterError) as exc: err_msg = traceback.format_exc() if "AccessDenied" in err_msg: raise StoreClientError(err_msg) from exc raise ConfigurationStoreError("Unable to get AWS AppConfig configuration file") from exc
Methods
def get_configuration(self) ‑> Dict[str, Any]
-
Fetch feature schema configuration from AWS AppConfig
If envelope is set, it'll extract and return feature flags from configuration, otherwise it'll return the entire configuration fetched from AWS AppConfig.
Raises
ConfigurationStoreError
- Any validation error or AppConfig error that can occur
Returns
Dict[str, Any]
- parsed JSON dictionary
Expand source code
def get_configuration(self) -> Dict[str, Any]: """Fetch feature schema configuration from AWS AppConfig If envelope is set, it'll extract and return feature flags from configuration, otherwise it'll return the entire configuration fetched from AWS AppConfig. Raises ------ ConfigurationStoreError Any validation error or AppConfig error that can occur Returns ------- Dict[str, Any] parsed JSON dictionary """ config = self.get_raw_configuration if self.envelope: self.logger.debug("Envelope enabled; extracting data from config", extra={"envelope": self.envelope}) config = jmespath_utils.extract_data_from_envelope( data=config, envelope=self.envelope, jmespath_options=self.jmespath_options ) return config