-
Notifications
You must be signed in to change notification settings - Fork 421
/
Copy pathuser_agent.py
169 lines (130 loc) · 5.5 KB
/
user_agent.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import logging
import os
from aws_lambda_powertools.shared.version import VERSION
powertools_version = VERSION
inject_header = True
try:
import botocore
except ImportError:
# if botocore failed to import, user might be using custom runtime and we can't inject header
inject_header = False
logger = logging.getLogger(__name__)
EXEC_ENV = os.environ.get("AWS_EXECUTION_ENV", "NA")
TARGET_SDK_EVENT = "request-created"
FEATURE_PREFIX = "PT"
DEFAULT_FEATURE = "no-op"
HEADER_NO_OP = f"{FEATURE_PREFIX}/{DEFAULT_FEATURE}/{powertools_version} PTEnv/{EXEC_ENV}"
def _initializer_botocore_session(session):
"""
This function is used to add an extra header for the User-Agent in the Botocore session,
as described in the pull request: https://github.com/boto/botocore/pull/2682
Parameters
----------
session : botocore.session.Session
The Botocore session to which the user-agent function will be registered.
Raises
------
Exception
If there is an issue while adding the extra header for the User-Agent.
"""
try:
session.register(TARGET_SDK_EVENT, _create_feature_function(DEFAULT_FEATURE))
except Exception:
logger.debug("Can't add extra header User-Agent")
def _create_feature_function(feature):
"""
Create and return the `add_powertools_feature` function.
The `add_powertools_feature` function is designed to be registered in boto3's event system.
When registered, it appends the given feature string to the User-Agent header of AWS SDK requests.
Parameters
----------
feature : str
The feature string to be appended to the User-Agent header.
Returns
-------
add_powertools_feature : Callable
The `add_powertools_feature` function that modifies the User-Agent header.
"""
def add_powertools_feature(request, **kwargs):
try:
headers = request.headers
header_user_agent = (
f"{headers['User-Agent']} {FEATURE_PREFIX}/{feature}/{powertools_version} PTEnv/{EXEC_ENV}"
)
# This function is exclusive to client and resources objects created in Powertools
# and must remove the no-op header, if present
if HEADER_NO_OP in headers["User-Agent"] and feature != DEFAULT_FEATURE:
# Remove HEADER_NO_OP + space
header_user_agent = header_user_agent.replace(f"{HEADER_NO_OP} ", "")
headers["User-Agent"] = f"{header_user_agent}"
except Exception:
logger.debug("Can't find User-Agent header")
return add_powertools_feature
# Add feature user-agent to given sdk boto3.session
def register_feature_to_session(session, feature):
"""
Register the given feature string to the event system of the provided boto3 session
and append the feature to the User-Agent header of the request
Parameters
----------
session : boto3.session.Session
The boto3 session to which the feature will be registered.
feature : str
The feature string to be appended to the User-Agent header, e.g., "streaming" in Powertools.
Raises
------
AttributeError
If the provided session does not have an event system.
"""
try:
session.events.register(TARGET_SDK_EVENT, _create_feature_function(feature))
except AttributeError as e:
logger.debug(f"session passed in doesn't have a event system:{e}")
# Add feature user-agent to given sdk boto3.client
def register_feature_to_client(client, feature):
"""
Register the given feature string to the event system of the provided boto3 client
and append the feature to the User-Agent header of the request
Parameters
----------
client : boto3.session.Session.client
The boto3 client to which the feature will be registered.
feature : str
The feature string to be appended to the User-Agent header, e.g., "streaming" in Powertools.
Raises
------
AttributeError
If the provided client does not have an event system.
"""
try:
client.meta.events.register(TARGET_SDK_EVENT, _create_feature_function(feature))
except AttributeError as e:
logger.debug(f"session passed in doesn't have a event system:{e}")
# Add feature user-agent to given sdk boto3.resource
def register_feature_to_resource(resource, feature):
"""
Register the given feature string to the event system of the provided boto3 resource
and append the feature to the User-Agent header of the request
Parameters
----------
resource : boto3.session.Session.resource
The boto3 resource to which the feature will be registered.
feature : str
The feature string to be appended to the User-Agent header, e.g., "streaming" in Powertools.
Raises
------
AttributeError
If the provided resource does not have an event system.
"""
try:
resource.meta.client.meta.events.register(TARGET_SDK_EVENT, _create_feature_function(feature))
except AttributeError as e:
logger.debug(f"resource passed in doesn't have a event system:{e}")
def inject_user_agent():
if inject_header:
# Some older botocore versions doesn't support register_initializer. In those cases, we disable the feature.
if not hasattr(botocore, "register_initializer"):
return
# Customize botocore session to inject Powertools header
# See: https://github.com/boto/botocore/pull/2682
botocore.register_initializer(_initializer_botocore_session)