From 0bba863d13edf758122d34b33eb1e891c5dc7c6d Mon Sep 17 00:00:00 2001 From: Mohamed Attia Date: Wed, 6 Mar 2024 15:52:57 +0100 Subject: [PATCH] Use a custom user agent when issuing HTTP requests. --- src/enlyze/api_clients/base.py | 13 +++++++- src/enlyze/constants.py | 3 ++ tests/enlyze/api_clients/test_base.py | 44 +++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/enlyze/api_clients/base.py b/src/enlyze/api_clients/base.py index 557deb3..1eec15c 100644 --- a/src/enlyze/api_clients/base.py +++ b/src/enlyze/api_clients/base.py @@ -8,10 +8,20 @@ import httpx from pydantic import BaseModel, ValidationError +from enlyze._version import VERSION from enlyze.auth import TokenAuth -from enlyze.constants import HTTPX_TIMEOUT +from enlyze.constants import HTTPX_TIMEOUT, USER_AGENT from enlyze.errors import EnlyzeError, InvalidTokenError +USER_AGENT_NAME_VERSION_SEPARATOR = "/" + + +@cache +def _construct_user_agent( + *, user_agent: str = USER_AGENT, version: str = VERSION +) -> str: + return f"{user_agent}{USER_AGENT_NAME_VERSION_SEPARATOR}{version}" + class ApiBaseModel(BaseModel): """Base class for ENLYZE platform API object models using pydantic @@ -60,6 +70,7 @@ def __init__( auth=TokenAuth(token), base_url=httpx.URL(base_url), timeout=timeout, + headers={"user-agent": _construct_user_agent()}, ) @cache diff --git a/src/enlyze/constants.py b/src/enlyze/constants.py index 337f312..1989dbe 100644 --- a/src/enlyze/constants.py +++ b/src/enlyze/constants.py @@ -22,3 +22,6 @@ #: The maximum number of variables that can be used in a single request when querying #: timeseries data. MAXIMUM_NUMBER_OF_VARIABLES_PER_TIMESERIES_REQUEST = 100 + +#: The user agent that the SDK identifies itself as when making HTTP requests +USER_AGENT = "enlyze-python" diff --git a/tests/enlyze/api_clients/test_base.py b/tests/enlyze/api_clients/test_base.py index 922db32..897cd81 100644 --- a/tests/enlyze/api_clients/test_base.py +++ b/tests/enlyze/api_clients/test_base.py @@ -7,11 +7,15 @@ from hypothesis import HealthCheck, given, settings from hypothesis import strategies as st +from enlyze._version import VERSION from enlyze.api_clients.base import ( + USER_AGENT_NAME_VERSION_SEPARATOR, ApiBaseClient, ApiBaseModel, PaginatedResponseBaseModel, + _construct_user_agent, ) +from enlyze.constants import USER_AGENT from enlyze.errors import EnlyzeError, InvalidTokenError @@ -83,6 +87,46 @@ def base_client(auth_token, string_model, base_url): yield client +@pytest.fixture +def custom_user_agent(): + return "custom-user-agent" + + +@pytest.fixture +def custom_user_agent_version(): + return "3.4.5" + + +class TestConstructUserAgent: + def test__construct_user_agent_with_defaults(self): + ua, version = _construct_user_agent().split(USER_AGENT_NAME_VERSION_SEPARATOR) + assert ua == USER_AGENT + assert version == VERSION + + def test__construct_user_agent_custom_agent(self, custom_user_agent): + ua, version = _construct_user_agent(user_agent=custom_user_agent).split( + USER_AGENT_NAME_VERSION_SEPARATOR + ) + assert ua == custom_user_agent + assert version == VERSION + + def test__construct_user_agent_custom_version(self, custom_user_agent_version): + ua, version = _construct_user_agent(version=custom_user_agent_version).split( + USER_AGENT_NAME_VERSION_SEPARATOR + ) + assert ua == USER_AGENT + assert version == custom_user_agent_version + + def test__construct_user_agent_custom_agent_and_version( + self, custom_user_agent, custom_user_agent_version + ): + ua, version = _construct_user_agent( + user_agent=custom_user_agent, version=custom_user_agent_version + ).split(USER_AGENT_NAME_VERSION_SEPARATOR) + assert ua == custom_user_agent + assert version == custom_user_agent_version + + @settings(suppress_health_check=[HealthCheck.function_scoped_fixture]) @given( token=st.text(string.printable, min_size=1),