Skip to content

Commit fac5dc0

Browse files
✨ Adds paginated method
2 parents af8373a + 69f61df commit fac5dc0

File tree

3 files changed

+87
-3
lines changed

3 files changed

+87
-3
lines changed

tests/test_request.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import json
12
import pytest
23
from unittest.mock import MagicMock
34
from wc_client.request import WCRequest
@@ -8,6 +9,12 @@ def __init__(self, content, status_code=200):
89
self.content = content
910
self.status_code = status_code
1011

12+
def json(self):
13+
# Decode bytes to string
14+
json_str = self.content.decode("utf-8")
15+
# Convert string to dict
16+
return json.loads(json_str)
17+
1118

1219
@pytest.fixture
1320
def wc_request():
@@ -74,3 +81,49 @@ def test_make_request(wc_request):
7481
)
7582
assert response.status_code == 200
7683
assert response.content == b'{"key": "value"}'
84+
85+
86+
def test_make_request_paginated(wc_request):
87+
# Mocking httpx.Client.get for the paginated case
88+
client = MagicMock()
89+
client.__enter__.return_value = client
90+
client.__exit__.return_value = False
91+
client.get.side_effect = [
92+
MockResponse(b'[{"foo": "bar"}, {"fizz": "buzz"}]', 200),
93+
MockResponse(b"[]", 200),
94+
]
95+
wc_request.client = client
96+
97+
data = wc_request.paginated(
98+
query_params={"param": "value"}, headers={"Authorization": "foo-bar"}
99+
)
100+
101+
assert client.get.call_count == 2
102+
103+
calls = client.get.call_args_list
104+
first_call = calls[0].kwargs
105+
second_call = calls[1].kwargs
106+
107+
assert first_call["url"] == "https://example.com/consumer/orders/1"
108+
assert first_call["headers"] == {
109+
"Accept": "application/json",
110+
"Authorization": "foo-bar",
111+
}
112+
assert first_call["params"] == {
113+
"param": "value",
114+
"per_page": WCRequest.DEFAULT_PAGE_LIMIT,
115+
"page": 1,
116+
}
117+
118+
assert second_call["url"] == "https://example.com/consumer/orders/1"
119+
assert second_call["headers"] == {
120+
"Accept": "application/json",
121+
"Authorization": "foo-bar",
122+
}
123+
assert second_call["params"] == {
124+
"param": "value",
125+
"per_page": WCRequest.DEFAULT_PAGE_LIMIT,
126+
"page": 2,
127+
}
128+
129+
assert data == [{"foo": "bar"}, {"fizz": "buzz"}]

wc_client/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Small WooCommerce API Client"""
22

3-
__version__ = "0.2.0"
3+
__version__ = "0.2.1"
44

55
from .client import WCClient
66

wc_client/request.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Any, Dict
1+
from typing import Any, Dict, List
22

33
import httpx
44

@@ -9,6 +9,7 @@ class WCRequest:
99
"""
1010

1111
METHODS = {"delete", "get", "patch", "post", "put"}
12+
DEFAULT_PAGE_LIMIT = 20
1213

1314
def __init__(self, base_url: str, headers: Dict, *args):
1415
"""
@@ -36,7 +37,6 @@ def _build_url(self) -> str:
3637
Returns:
3738
str: The URL for the request
3839
"""
39-
print(self._url_path)
4040
return "/".join(self._url_path)
4141

4242
def _update_headers(self, headers):
@@ -83,5 +83,36 @@ def make_request(body=None, query_params=None, headers=None):
8383

8484
return make_request
8585

86+
elif resource == "paginated":
87+
88+
def make_request_paginated(query_params={}, headers=None) -> List[Dict]:
89+
if headers:
90+
self._update_headers(headers)
91+
92+
query_params["per_page"] = self.DEFAULT_PAGE_LIMIT
93+
query_params["page"] = 1
94+
95+
data = []
96+
97+
with self.client as client:
98+
while True:
99+
res = client.get(
100+
url=self._build_url(),
101+
headers=self.headers,
102+
params=query_params.copy(),
103+
)
104+
105+
res_json = res.json()
106+
data.extend(res_json)
107+
108+
if len(res_json) == 0:
109+
break
110+
111+
query_params["page"] += 1
112+
113+
return data
114+
115+
return make_request_paginated
116+
86117
else:
87118
return self._(resource)

0 commit comments

Comments
 (0)