Skip to content

Commit 7aac81c

Browse files
committed
Add user_agent interceptor test
1 parent 6c6458b commit 7aac81c

File tree

3 files changed

+89
-13
lines changed

3 files changed

+89
-13
lines changed

packages/smithy-http/src/smithy_http/interceptors/user_agent.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class UserAgentInterceptor(Interceptor[Any, None, HTTPRequest, None]):
1717
def read_before_execution(
1818
self, context: InterceptorContext[Any, None, None, None]
1919
) -> None:
20-
context.properties["user_agent"] = _UserAgentBuilder.from_environment().build()
20+
context.properties["user_agent"] = UserAgentBuilder.from_environment().build()
2121

2222
def modify_before_signing(
2323
self, context: InterceptorContext[Any, None, HTTPRequest, None]
@@ -42,24 +42,23 @@ def modify_before_signing(
4242
_USERAGENT_SDK_NAME = "python"
4343

4444

45-
class _UserAgentBuilder:
45+
class UserAgentBuilder:
4646
def __init__(
4747
self,
4848
*,
49-
platform_name: str | None,
50-
platform_version: str | None,
51-
platform_machine: str | None,
52-
python_version: str | None,
53-
python_implementation: str | None,
49+
platform_name: str | None = None,
50+
platform_version: str | None = None,
51+
platform_machine: str | None = None,
52+
python_version: str | None = None,
53+
python_implementation: str | None = None,
5454
sdk_version: str | None = None,
5555
) -> None:
5656
self._platform_name = platform_name
5757
self._platform_version = platform_version
5858
self._platform_machine = platform_machine
5959
self._python_version = python_version
6060
self._python_implementation = python_implementation
61-
# TODO: Allow configuration through context
62-
self._sdk_version = smithy_core.__version__
61+
self._sdk_version = sdk_version
6362

6463
@classmethod
6564
def from_environment(cls) -> Self:
@@ -69,20 +68,26 @@ def from_environment(cls) -> Self:
6968
platform_machine=platform.machine(),
7069
python_version=platform.python_version(),
7170
python_implementation=platform.python_implementation(),
71+
sdk_version=smithy_core.__version__,
7272
)
7373

7474
def build(self) -> UserAgent:
7575
user_agent = UserAgent()
76-
user_agent.sdk_metadata.append(
77-
UserAgentComponent(prefix=_USERAGENT_SDK_NAME, name=self._sdk_version)
78-
)
76+
user_agent.sdk_metadata.extend(self._build_sdk_metadata())
7977
user_agent.ua_metadata.append(UserAgentComponent(prefix="ua", name="2.1"))
8078
user_agent.os_metadata.extend(self._build_os_metadata())
8179
user_agent.os_metadata.extend(self._build_architecture_metadata())
8280
user_agent.language_metadata.extend(self._build_language_metadata())
8381

8482
return user_agent
8583

84+
def _build_sdk_metadata(self) -> list[UserAgentComponent]:
85+
if self._sdk_version:
86+
return [
87+
UserAgentComponent(prefix=_USERAGENT_SDK_NAME, name=self._sdk_version)
88+
]
89+
return []
90+
8691
def _build_os_metadata(self) -> list[UserAgentComponent]:
8792
"""Build the OS/platform components of the User-Agent header string.
8893
@@ -97,7 +102,7 @@ def _build_os_metadata(self) -> list[UserAgentComponent]:
97102
* ``os/other``
98103
* ``os/other md/foobar#1.2.3``
99104
"""
100-
if self._platform_name is None:
105+
if self._platform_name is None or self._platform_name == "":
101106
return [UserAgentComponent("os", "other")]
102107

103108
plt_name_lower = self._platform_name.lower()
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import platform
2+
3+
import smithy_core
4+
from smithy_http.interceptors.user_agent import UserAgentBuilder
5+
6+
7+
def test_from_environment(monkeypatch): # type: ignore
8+
monkeypatch.setattr(platform, "system", lambda: "Linux") # type: ignore
9+
monkeypatch.setattr(platform, "release", lambda: "5.4.228-131.415.AMZN2.X86_64") # type: ignore
10+
monkeypatch.setattr(platform, "python_version", lambda: "4.3.2") # type: ignore
11+
monkeypatch.setattr(platform, "python_implementation", lambda: "Cpython") # type: ignore
12+
monkeypatch.setattr(smithy_core, "__version__", "1.2.3") # type: ignore
13+
14+
user_agent = str(UserAgentBuilder.from_environment().build())
15+
assert "python/1.2.3" in user_agent
16+
assert "os/linux#5.4.228-131.415.AMZN2.X86_64" in user_agent
17+
assert "md/arch#arm64" in user_agent
18+
assert "lang/python#4.3.2" in user_agent
19+
assert "md/pyimpl#Cpython" in user_agent
20+
21+
22+
def test_build_adds_sdk_metadata():
23+
user_agent = UserAgentBuilder(sdk_version="1.2.3").build()
24+
assert "python/1.2.3" in str(user_agent)
25+
26+
27+
def test_build_adds_ua_metadata():
28+
user_agent = UserAgentBuilder().build()
29+
assert "ua/2.1" in str(user_agent)
30+
31+
32+
def test_build_os_defaults_to_other():
33+
user_agent = UserAgentBuilder().build()
34+
assert "os/other" in str(user_agent)
35+
36+
37+
def test_build_os_lowercases_platform():
38+
user_agent = UserAgentBuilder(platform_name="LINUX").build()
39+
assert "os/linux" in str(user_agent)
40+
41+
42+
def test_build_os_maps_platform_names():
43+
user_agent = UserAgentBuilder(platform_name="darwin").build()
44+
assert "os/macos" in str(user_agent)
45+
46+
47+
def test_build_os_includes_version():
48+
user_agent = UserAgentBuilder(platform_name="linux", platform_version="5.4").build()
49+
assert "os/linux#5.4" in str(user_agent)
50+
51+
52+
def test_build_os_other_platform():
53+
user_agent = UserAgentBuilder(
54+
platform_name="myos", platform_version="0.0.1"
55+
).build()
56+
assert "os/other md/myos#0.0.1" in str(user_agent)
57+
58+
59+
def test_build_arch_adds_md():
60+
user_agent = UserAgentBuilder(platform_machine="x86_64").build()
61+
assert "md/arch#x86_64" in str(user_agent)
62+
63+
64+
def test_build_language_version():
65+
user_agent = UserAgentBuilder(python_version="3.12").build()
66+
assert "lang/python#3.12" in str(user_agent)
67+
68+
69+
def test_build_language_implementation():
70+
user_agent = UserAgentBuilder(python_implementation="CPython").build()
71+
assert "md/pyimpl#CPython" in str(user_agent)

0 commit comments

Comments
 (0)