Skip to content

Commit bc44c24

Browse files
Add HTTP proxy support via environment variables (#29)
supports HTTP_PROXY & HTTPS_PROXY env vars
1 parent 9322cf9 commit bc44c24

2 files changed

Lines changed: 46 additions & 1 deletion

File tree

armis_sdk/core/armis_client.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class ArmisClient: # pylint: disable=too-few-public-methods
4444
1. Authenticating requests.
4545
2. Retrying of failed requests (when applicable).
4646
3. Pagination of requests (when applicable).
47+
4. Proxy configuration via HTTPS_PROXY and HTTP_PROXY environment variables.
4748
"""
4849

4950
def __init__(
@@ -91,14 +92,22 @@ def client(self, retries: Optional[int] = None, backoff: Optional[float] = None)
9192
retries = retries if retries is not None else self._default_retries
9293
backoff = backoff if backoff is not None else self._default_backoff
9394
retry = Retry(total=retries, backoff_factor=backoff)
95+
96+
if proxy := self._get_proxy_config():
97+
http_transport = httpx.AsyncHTTPTransport(proxy=proxy)
98+
transport = RetryTransport(retry=retry, transport=http_transport)
99+
else:
100+
transport = RetryTransport(retry=retry)
101+
94102
return httpx.AsyncClient(
95103
auth=self._auth,
96104
base_url=self._base_url,
97105
headers={
98106
"User-Agent": self._user_agent,
99107
"Armis-API-Client-Id": self._client_id,
100108
},
101-
transport=RetryTransport(retry=retry),
109+
transport=transport,
110+
trust_env=True,
102111
)
103112

104113
async def list(self, url: str, key: str) -> AsyncIterator[dict]:
@@ -142,3 +151,7 @@ async def main():
142151
for item in items:
143152
yield item
144153
from_ = data.get("next")
154+
155+
def _get_proxy_config(self):
156+
"""Get proxy configuration from environment variables."""
157+
return os.getenv("HTTPS_PROXY") or os.getenv("HTTP_PROXY")

tests/armis_sdk/core/armis_client_test.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import platform
33

44
import httpx
5+
import pytest
56
import pytest_httpx
67

78
from armis_sdk.core.armis_client import ArmisClient
@@ -149,3 +150,34 @@ async def test_list_with_multiple_pages(
149150
{"id": "4", "name": "mock_site_4"},
150151
{"id": "5", "name": "mock_site_5"},
151152
]
153+
154+
155+
@pytest.mark.parametrize(
156+
["env_var", "proxy_url", "expected_proxy"],
157+
[
158+
(
159+
"HTTP_PROXY",
160+
"http://test-proxy:8080?b=1&a=2",
161+
"http://test-proxy:8080/?a=2&b=1",
162+
),
163+
(
164+
"HTTPS_PROXY",
165+
"https://user:[email protected]:8080?b=1&a=2&c=3",
166+
"https://user:[email protected]:8080/?c=3&b=1&a=2",
167+
),
168+
],
169+
)
170+
async def test_proxy(monkeypatch, httpx_mock, env_var, proxy_url, expected_proxy):
171+
monkeypatch.setenv(env_var, proxy_url)
172+
173+
# proxy_url must match,
174+
# Order of parameters in the query string does not matter
175+
httpx_mock.add_response(
176+
url="https://mock_tenant.armis.com/mock/endpoint",
177+
proxy_url=expected_proxy,
178+
json={"ok": True},
179+
)
180+
181+
async with ArmisClient().client() as client:
182+
resp = await client.get("/mock/endpoint")
183+
assert resp.json() == {"ok": True}

0 commit comments

Comments
 (0)