Skip to content

Commit 07c9f8f

Browse files
Adding some small changes
1 parent 8ff0453 commit 07c9f8f

File tree

7 files changed

+128
-11
lines changed

7 files changed

+128
-11
lines changed

aws_lambda_powertools/utilities/feature_flags/appconfig.py

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import traceback
33
from typing import TYPE_CHECKING, Any, Dict, Optional, Union, cast
44

5+
import boto3
56
from botocore.config import Config
67

78
from aws_lambda_powertools.utilities import jmespath_utils
@@ -30,7 +31,9 @@ def __init__(
3031
envelope: Optional[str] = "",
3132
jmespath_options: Optional[Dict] = None,
3233
logger: Optional[Union[logging.Logger, Logger]] = None,
33-
sdk_client: Optional["AppConfigDataClient"] = None,
34+
boto_config: Optional[Config] = None,
35+
boto3_session: Optional[boto3.session.Session] = None,
36+
boto3_client: Optional["AppConfigDataClient"] = None,
3437
):
3538
"""This class fetches JSON schemas from AWS AppConfig
3639
@@ -52,23 +55,28 @@ def __init__(
5255
Alternative JMESPath options to be included when filtering expr
5356
logger: A logging object
5457
Used to log messages. If None is supplied, one will be created.
55-
sdk_client: Optional[AppConfigDataClient]
56-
AppConfigData boto3 client, `sdk_config` will be ignored if this value is provided.
58+
boto_config: botocore.config.Config, optional
59+
Botocore configuration to pass during client initialization
60+
boto3_session : boto3.Session, optional
61+
Boto3 session to use for AWS API communication
62+
boto3_client : AppConfigDataClient, optional
63+
Boto3 AppConfigDataClient Client to use, boto3_session and boto_config will be ignored if both are provided
5764
"""
5865
super().__init__()
5966
self.logger = logger or logging.getLogger(__name__)
6067
self.environment = environment
6168
self.application = application
6269
self.name = name
6370
self.cache_seconds = max_age
64-
self.config = sdk_config
71+
self.config = sdk_config or boto_config
6572
self.envelope = envelope
6673
self.jmespath_options = jmespath_options
6774
self._conf_store = AppConfigProvider(
6875
environment=environment,
6976
application=application,
70-
config=sdk_config,
71-
boto3_client=sdk_client,
77+
config=sdk_config or boto_config,
78+
boto3_client=boto3_client,
79+
boto3_session=boto3_session,
7280
)
7381

7482
@property

docs/utilities/feature_flags.md

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,10 +503,11 @@ These are the available options for further customization.
503503
| **name** | `""` | AWS AppConfig Configuration name, e.g `features` |
504504
| **envelope** | `None` | JMESPath expression to use to extract feature flags configuration from AWS AppConfig configuration |
505505
| **max_age** | `5` | Number of seconds to cache feature flags configuration fetched from AWS AppConfig |
506-
| **sdk_config** | `None` | [Botocore Config object](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html){target="_blank"} |
507506
| **jmespath_options** | `None` | For advanced use cases when you want to bring your own [JMESPath functions](https://github.com/jmespath/jmespath.py#custom-functions){target="_blank" rel="nofollow"} |
508507
| **logger** | `logging.Logger` | Logger to use for debug. You can optionally supply an instance of Powertools for AWS Lambda (Python) Logger. |
509-
| **sdk_client** | `None` | [AppConfigData boto3 client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/appconfigdata.html#AppConfigData.Client){target="_blank"} |
508+
| **boto3_client** | `None` | [AppConfigData boto3 client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/appconfigdata.html#AppConfigData.Client){target="_blank"} |
509+
| **boto3_session** | `None` | [Boto3 session](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html){target="_blank"} |
510+
| **boto_config** | `None` | [Botocore config](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html){target="_blank"} |
510511

511512
=== "appconfig_provider_options.py"
512513

@@ -526,6 +527,27 @@ These are the available options for further customization.
526527
--8<-- "examples/feature_flags/src/appconfig_provider_options_features.json"
527528
```
528529

530+
#### Customizing boto configuration
531+
532+
<!-- markdownlint-disable MD013 -->
533+
The **`boto_config`** , **`boto3_session`**, and **`boto3_client`** parameters enable you to pass in a custom [botocore config object](https://botocore.amazonaws.com/v1/documentation/api/latest/reference/config.html){target="_blank"}, [boto3 session](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/session.html){target="_blank"}, or a [boto3 client](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/core/boto3.html){target="_blank"} when constructing the AppConfig store provider.
534+
<!-- markdownlint-enable MD013 -->
535+
536+
=== "custom_boto_session_feature_flags.py"
537+
```python hl_lines="8 14"
538+
--8<-- "examples/feature_flags/src/custom_boto_session_feature_flags.py"
539+
```
540+
541+
=== "custom_boto_config_feature_flags.py"
542+
```python hl_lines="8 14"
543+
--8<-- "examples/feature_flags/src/custom_boto_config_feature_flags.py"
544+
```
545+
546+
=== "custom_boto_client_feature_flags.py"
547+
```python hl_lines="8 14"
548+
--8<-- "examples/feature_flags/src/custom_boto_client_feature_flags.py"
549+
```
550+
529551
### Create your own store provider
530552

531553
You can create your own custom FeatureFlags store provider by inheriting the `StoreProvider` class, and implementing both `get_raw_configuration()` and `get_configuration()` methods to retrieve the configuration from your custom store.

examples/feature_flags/src/appconfig_provider_options.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def _func_special_decoder(self, features):
2626
name="features",
2727
max_age=120,
2828
envelope="special_decoder(features)", # using a custom function defined in CustomFunctions Class
29-
sdk_config=boto_config,
29+
boto_config=boto_config,
3030
jmespath_options=custom_jmespath_options,
3131
)
3232

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import Any
2+
3+
import boto3
4+
5+
from aws_lambda_powertools.utilities.feature_flags import AppConfigStore, FeatureFlags
6+
from aws_lambda_powertools.utilities.typing import LambdaContext
7+
8+
boto3_client = boto3.client("ssm")
9+
10+
app_config = AppConfigStore(
11+
environment="dev",
12+
application="product-catalogue",
13+
name="features",
14+
boto3_client=boto3_client,
15+
)
16+
17+
feature_flags = FeatureFlags(store=app_config)
18+
19+
20+
def lambda_handler(event: dict, context: LambdaContext):
21+
apply_discount: Any = feature_flags.evaluate(name="ten_percent_off_campaign", default=False)
22+
23+
price: Any = event.get("price")
24+
25+
if apply_discount:
26+
# apply 10% discount to product
27+
price = price * 0.9
28+
29+
return {"price": price}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import Any
2+
3+
from botocore.config import Config
4+
5+
from aws_lambda_powertools.utilities.feature_flags import AppConfigStore, FeatureFlags
6+
from aws_lambda_powertools.utilities.typing import LambdaContext
7+
8+
boto_config = Config(read_timeout=10, retries={"total_max_attempts": 2})
9+
10+
app_config = AppConfigStore(
11+
environment="dev",
12+
application="product-catalogue",
13+
name="features",
14+
boto_config=boto_config,
15+
)
16+
17+
feature_flags = FeatureFlags(store=app_config)
18+
19+
20+
def lambda_handler(event: dict, context: LambdaContext):
21+
apply_discount: Any = feature_flags.evaluate(name="ten_percent_off_campaign", default=False)
22+
23+
price: Any = event.get("price")
24+
25+
if apply_discount:
26+
# apply 10% discount to product
27+
price = price * 0.9
28+
29+
return {"price": price}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from typing import Any
2+
3+
import boto3
4+
5+
from aws_lambda_powertools.utilities.feature_flags import AppConfigStore, FeatureFlags
6+
from aws_lambda_powertools.utilities.typing import LambdaContext
7+
8+
boto3_session = boto3.session.Session()
9+
10+
app_config = AppConfigStore(
11+
environment="dev",
12+
application="product-catalogue",
13+
name="features",
14+
boto3_session=boto3_session,
15+
)
16+
17+
feature_flags = FeatureFlags(store=app_config)
18+
19+
20+
def lambda_handler(event: dict, context: LambdaContext):
21+
apply_discount: Any = feature_flags.evaluate(name="ten_percent_off_campaign", default=False)
22+
23+
price: Any = event.get("price")
24+
25+
if apply_discount:
26+
# apply 10% discount to product
27+
price = price * 0.9
28+
29+
return {"price": price}

tests/functional/feature_flags/_boto3/test_feature_flags.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ def init_feature_flags(
7878
application=application,
7979
name=name,
8080
max_age=600,
81-
sdk_config=config,
8281
envelope=envelope,
8382
jmespath_options=jmespath_options,
84-
sdk_client=client,
83+
boto_config=config,
84+
boto3_client=client,
8585
)
8686
feature_flags: FeatureFlags = FeatureFlags(store=app_conf_fetcher)
8787
return feature_flags

0 commit comments

Comments
 (0)