Skip to content

Commit e052d52

Browse files
committed
#MPT-12324 HTTP layer with Httpx
1 parent 994e538 commit e052d52

File tree

6 files changed

+166
-13
lines changed

6 files changed

+166
-13
lines changed

mpt_api_client/client.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

mpt_api_client/http/client.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import httpx
2+
3+
4+
class MPTClient(httpx.Client):
5+
"""A client for interacting with Softwareone Marketplace Platform API."""
6+
7+
def __init__(
8+
self,
9+
*,
10+
base_url: str,
11+
api_token: str,
12+
timeout: float = 5.0,
13+
retries: int = 0,
14+
):
15+
"""
16+
Initializes the MPTClient.
17+
18+
Args:
19+
base_url: The base URL of the API.
20+
api_token: The API token.
21+
timeout: The timeout for requests.
22+
retries: The number of retries for requests. If set to 0, no retries are performed.
23+
24+
"""
25+
self.api_token = api_token
26+
base_headers = {
27+
"User-Agent": "swo-marketplace-client/1.0",
28+
"Authorization": f"Bearer {api_token}",
29+
}
30+
super().__init__(
31+
base_url=base_url,
32+
headers=base_headers,
33+
timeout=timeout,
34+
transport=httpx.HTTPTransport(retries=retries),
35+
)

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ classifiers = [
1919
"Programming Language :: Python :: 3.12",
2020
"Topic :: Utilities",
2121
]
22-
dependencies = []
22+
dependencies = [
23+
"httpx>=0.28.1"
24+
]
2325

2426
[dependency-groups]
2527
dev = [

tests/http/test_client.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import pytest
2+
from httpx import ConnectTimeout, MockTransport, Request, Response, codes
3+
4+
from mpt_api_client.http.client import MPTClient
5+
6+
API_TOKEN = "test-token"
7+
API_URL = "https://api.example.com"
8+
9+
10+
@pytest.fixture
11+
def mock_transport() -> MockTransport:
12+
def handler_request(request: Request): # noqa: WPS430
13+
if request.url.path == "/":
14+
return Response(codes.OK, json={"message": "Hello, World!"})
15+
if request.url.path == "/timeout":
16+
raise ConnectTimeout("Mock Timeout")
17+
return Response(codes.NOT_FOUND, json={"message": "Not Found"})
18+
19+
return MockTransport(handler=handler_request)
20+
21+
22+
@pytest.fixture
23+
def mock_api_client(mocker, mock_transport: MockTransport):
24+
transport_mock = mocker.patch("mpt_api_client.http.client.httpx.HTTPTransport")
25+
transport_mock.return_value = mock_transport
26+
return MPTClient(base_url=API_URL, api_token=API_TOKEN)
27+
28+
29+
def test_mpt_client_initialization():
30+
client = MPTClient(base_url=API_URL, api_token=API_TOKEN)
31+
32+
assert client.api_token == API_TOKEN
33+
assert client.base_url == API_URL
34+
35+
36+
def test_mpt_client_headers():
37+
client = MPTClient(base_url=API_URL, api_token=API_TOKEN)
38+
39+
assert client.headers["Authorization"] == "Bearer test-token"
40+
assert client.headers["User-Agent"] == "swo-marketplace-client/1.0"
41+
42+
43+
def test_mpt_client_timeout_and_retries():
44+
client = MPTClient(
45+
base_url=API_URL,
46+
api_token=API_TOKEN,
47+
timeout=12, # noqa: WPS432
48+
retries=2, # noqa: WPS432
49+
)
50+
51+
assert client._timeout.connect == 12 # noqa: WPS432, SLF001
52+
53+
54+
def test_mock(mock_api_client: MPTClient):
55+
success_response = mock_api_client.get("/")
56+
57+
with pytest.raises(ConnectTimeout):
58+
mock_api_client.get("/timeout")
59+
60+
not_found_response = mock_api_client.get("/not-found")
61+
62+
assert success_response.status_code == codes.OK
63+
assert success_response.json() == {"message": "Hello, World!"}
64+
assert not_found_response.status_code == codes.NOT_FOUND

tests/test_client.py

Lines changed: 0 additions & 9 deletions
This file was deleted.

uv.lock

Lines changed: 64 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)