Skip to content

Commit f5ec1a2

Browse files
committed
#MPT-12324 HTTP layer with Httpx
1 parent a614f0f commit f5ec1a2

File tree

6 files changed

+175
-13
lines changed

6 files changed

+175
-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: 4 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.*"
24+
]
2325

2426
[dependency-groups]
2527
dev = [
@@ -35,6 +37,7 @@ dev = [
3537
"pytest-randomly==3.16.*",
3638
"pytest-xdist==3.6.*",
3739
"responses==0.25.*",
40+
"respx>=0.22.0",
3841
"ruff==0.12.*",
3942
"typing-extensions==4.13.*",
4043
"wemake-python-styleguide==1.3.*",

tests/http/test_client.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import pytest
2+
import respx
3+
from httpx import ConnectTimeout, MockTransport, Request, Response, codes
4+
5+
from mpt_api_client.http.client import MPTClient
6+
7+
API_TOKEN = "test-token"
8+
API_URL = "https://api.example.com"
9+
10+
11+
@pytest.fixture
12+
def mpt_client():
13+
return MPTClient(base_url=API_URL, api_token=API_TOKEN)
14+
15+
16+
def test_mpt_client_initialization():
17+
client = MPTClient(base_url=API_URL, api_token=API_TOKEN)
18+
19+
assert client.api_token == API_TOKEN
20+
assert client.base_url == API_URL
21+
22+
23+
def test_mpt_client_headers():
24+
client = MPTClient(base_url=API_URL, api_token=API_TOKEN)
25+
26+
assert client.headers["Authorization"] == "Bearer test-token"
27+
assert client.headers["User-Agent"] == "swo-marketplace-client/1.0"
28+
29+
30+
@respx.mock
31+
def test_mock_call_success(mpt_client: MPTClient):
32+
success_route = respx.get(f"{API_URL}/").mock(return_value=Response(200, json={"message": "Hello, World!"}))
33+
34+
success_response = mpt_client.get("/")
35+
36+
assert success_response.status_code == codes.OK
37+
assert success_response.json() == {"message": "Hello, World!"}
38+
assert success_route.called
39+
40+
41+
@respx.mock
42+
def test_mock_call_failure(mpt_client: MPTClient):
43+
timeout_route = respx.get(f"{API_URL}/timeout").mock(side_effect=ConnectTimeout("Mock Timeout"))
44+
45+
with pytest.raises(ConnectTimeout):
46+
mpt_client.get("/timeout")
47+
48+
assert timeout_route.called
49+
50+
51+
@respx.mock
52+
def test_mock_call_failure_with_retries(mpt_client: MPTClient):
53+
not_found_route = respx.get(f"{API_URL}/not-found").mock(side_effect=Response(codes.NOT_FOUND, json={"message": "Not Found"}))
54+
55+
not_found_response = mpt_client.get("/not-found")
56+
57+
assert not_found_response.status_code == codes.NOT_FOUND
58+
assert not_found_route.called

tests/test_client.py

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

uv.lock

Lines changed: 78 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)