Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ all_contacts = api_client.crm.contacts.get_all()

Please note that pagination is used under the hood to get all results.

Pass `limit` to cap the total number of results, for example `get_all(limit=100)`.
Omitting it fetches all results. A limit of zero returns an empty list without an API
request; negative limits raise `ValueError`.

## Search

`do_search` method is available for all objects (Companies, Contacts, Deals and etc).
Expand Down
5 changes: 5 additions & 0 deletions hubspot/utils/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ def fetch_all(get_page_api_client, **kwargs):

max_page_size = PROPERTY_HISTORY_MAX_SIZE if "properties_with_history" in kwargs else PAGE_MAX_SIZE
limit = kwargs.pop("limit", None)
if limit is not None:
if limit < 0:
raise ValueError("limit must be non-negative")
if limit == 0:
return results
total_fetched = 0

while True:
Expand Down
39 changes: 39 additions & 0 deletions tests/spec/utils/test_fetch_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from types import SimpleNamespace
from unittest.mock import Mock

import pytest

from hubspot.utils.objects import fetch_all


def test_zero_limit_does_not_fetch():
client = Mock()
client.get_page.return_value = SimpleNamespace(results=[1], paging=None)
assert fetch_all(client, limit=0) == []
client.get_page.assert_not_called()


def test_negative_limit_does_not_fetch():
client = Mock()
client.get_page.return_value = SimpleNamespace(results=[1], paging=None)
with pytest.raises(ValueError, match="limit"):
fetch_all(client, limit=-1)
client.get_page.assert_not_called()


@pytest.mark.parametrize("limit", [None, 101])
def test_multiple_pages(limit):
client = Mock()
client.get_page.side_effect = [
SimpleNamespace(
results=list(range(100)),
paging=SimpleNamespace(next=SimpleNamespace(after="next")),
),
SimpleNamespace(results=[100], paging=None),
]
assert fetch_all(client, limit=limit) == list(range(101))
assert client.get_page.call_args_list[0].kwargs == {"after": None, "limit": 100}
assert client.get_page.call_args_list[1].kwargs == {
"after": "next",
"limit": 1 if limit else 100,
}