Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c53e384

Browse files
committedMay 18, 2023
feat(user-agent): using default botocore initializer + minor changes
1 parent 37bf656 commit c53e384

File tree

3 files changed

+60
-41
lines changed

3 files changed

+60
-41
lines changed
 

‎aws_lambda_powertools/__init__.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@
44

55
from pathlib import Path
66

7-
from .logging import Logger
8-
from .metrics import Metrics, single_metric
9-
from .package_logger import set_package_logger_handler
10-
from .shared import user_agent
11-
from .tracing import Tracer
7+
from aws_lambda_powertools.logging import Logger
8+
from aws_lambda_powertools.metrics import Metrics, single_metric
9+
from aws_lambda_powertools.package_logger import set_package_logger_handler
10+
from aws_lambda_powertools.shared.user_agent import inject_user_agent
11+
from aws_lambda_powertools.shared.version import VERSION
12+
from aws_lambda_powertools.tracing import Tracer
1213

14+
__version__ = VERSION
1315
__author__ = """Amazon Web Services"""
1416
__all__ = [
1517
"Logger",
@@ -22,4 +24,4 @@
2224

2325
set_package_logger_handler()
2426

25-
user_agent.inject_user_agent()
27+
inject_user_agent()
Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,79 @@
11
import logging
22
import os
3-
import sys
43

5-
# Since Python 3.8 there is a built-in. Remove this when support for Python3.7 is dropped
6-
# See https://docs.python.org/3/library/importlib.metadata.html
7-
if sys.version_info >= (3, 8):
8-
from importlib.metadata import version
9-
else:
10-
from importlib_metadata import version
4+
from aws_lambda_powertools.shared.version import VERSION
115

12-
powertools_version = version("aws-lambda-powertools")
6+
powertools_version = VERSION
7+
inject_header = True
138

149
try:
15-
from botocore import handlers
10+
import botocore
1611
except ImportError:
17-
# if botocore failed to import, user might be using custom runtime. We can ignore here
18-
handlers = None
12+
# if botocore failed to import, user might be using custom runtime and we can't inject header
13+
inject_header = False
1914

2015
logger = logging.getLogger(__name__)
2116

22-
EXEC_ENV = os.getenv("AWS_EXECUTION_ENV", "NA")
23-
TARGET_SDK_EVENT = "request-created"
24-
FEATURE_PREFIX = "PT"
17+
EXEC_ENV: str = os.environ.get("AWS_EXECUTION_ENV", "NA")
18+
TARGET_SDK_EVENT: str = "request-created"
19+
FEATURE_PREFIX: str = "PT"
20+
HEADER_NO_OP: str = f"{FEATURE_PREFIX}/no-op/{powertools_version} PTEnv/{EXEC_ENV}"
2521

2622

27-
# In case of no Powertools utility: PT/no-op/2.15.0 PTEnv/AWS_Lambda_python3.9
28-
def _add_powertools_version(request, **kwargs):
23+
def _initializer_botocore_session(session):
2924
try:
30-
headers = request.headers
31-
headers["User-Agent"] = f"{headers['User-Agent']} {FEATURE_PREFIX}/no-op/{powertools_version} PTEnv/{EXEC_ENV}"
25+
session.user_agent_extra = HEADER_NO_OP
3226
except Exception:
33-
logger.debug("Missing header User-Agent")
27+
logger.debug("Can't add extra header User-Agent")
3428

3529

36-
# creates the `add_feature_string` function with given feature parameter
3730
def _create_feature_function(feature):
3831
def add_powertools_feature(request, **kwargs):
39-
headers = request.headers
40-
# Actually, only one handler can be registered, registering a new one will replace the prev handler
41-
# We don't need to replace/detect previous registered user-agent
42-
headers[
43-
"User-Agent"
44-
] = f"{headers['User-Agent']} {FEATURE_PREFIX}/{feature}/{powertools_version} PTEnv/{EXEC_ENV}"
45-
46-
# return created function
32+
try:
33+
headers = request.headers
34+
header_user_agent: str = (
35+
f"{headers['User-Agent']} {FEATURE_PREFIX}/{feature}/{powertools_version} PTEnv/{EXEC_ENV}"
36+
)
37+
38+
# This function is exclusive to client and resources objects created in Powertools
39+
# and must remove the no-op header, if present
40+
if HEADER_NO_OP in headers["User-Agent"]:
41+
# Remove HEADER_NO_OP + space
42+
header_user_agent = header_user_agent.replace(f"{HEADER_NO_OP} ", "")
43+
44+
headers["User-Agent"] = f"{header_user_agent}"
45+
except Exception:
46+
logger.debug("Can't find User-Agent header")
47+
4748
return add_powertools_feature
4849

4950

50-
# add feature user-agent to given sdk boto3.session
51+
# Add feature user-agent to given sdk boto3.session
5152
def register_feature_to_session(session, feature):
5253
try:
5354
session.events.register(TARGET_SDK_EVENT, _create_feature_function(feature))
5455
except AttributeError as e:
5556
logger.debug(f"session passed in doesn't have a event system:{e}")
5657

5758

58-
# add feature user-agent to given sdk boto3.client
59+
# Add feature user-agent to given sdk boto3.client
5960
def register_feature_to_client(client, feature):
6061
try:
6162
client.meta.events.register(TARGET_SDK_EVENT, _create_feature_function(feature))
6263
except AttributeError as e:
6364
logger.debug(f"session passed in doesn't have a event system:{e}")
6465

6566

66-
# add feature user-agent to given sdk boto3.resource
67+
# Add feature user-agent to given sdk boto3.resource
6768
def register_feature_to_resource(resource, feature):
6869
try:
6970
resource.meta.client.meta.events.register(TARGET_SDK_EVENT, _create_feature_function(feature))
7071
except AttributeError as e:
7172
logger.debug(f"resource passed in doesn't have a event system:{e}")
7273

7374

74-
# register add_pt_version for all AWS SDK in runtime
7575
def inject_user_agent():
76-
if handlers:
77-
# register add_user_agent to BUILTIN_HANDLERS so every aws sdk session will have this event registered
78-
handlers.BUILTIN_HANDLERS.append((TARGET_SDK_EVENT, _add_powertools_version))
76+
if inject_header:
77+
# Customize botocore session to inject Powertools header
78+
# See: https://github.com/boto/botocore/pull/2682
79+
botocore.register_initializer(_initializer_botocore_session)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
This file serves to create a constant that informs
3+
the current version of the Powertools package and exposes it in the main module
4+
5+
Since Python 3.8 there the built-in importlib.metadata
6+
When support for Python3.7 is dropped, we can remove the optional importlib_metadata dependency
7+
See: https://docs.python.org/3/library/importlib.metadata.html
8+
"""
9+
import sys
10+
11+
if sys.version_info >= (3, 8):
12+
from importlib.metadata import version
13+
else:
14+
from importlib_metadata import version
15+
16+
VERSION = version("aws-lambda-powertools")

0 commit comments

Comments
 (0)
Please sign in to comment.