mirror of
https://github.com/thousandeyes/thousandeyes-sdk-python.git
synced 2026-02-04 18:25:29 +00:00
Compare commits
No commits in common. "31826120699efb0def40cc5ff2902e78c922385f" and "abea9a244afa082e78e5ca6e46ad1f8112e91651" have entirely different histories.
3182612069
...
abea9a244a
@ -2,28 +2,18 @@
|
|||||||
|
|
||||||
This package provides core functionality for interacting with the ThousandEyes API and should be installed before using any of the published SDKs.
|
This package provides core functionality for interacting with the ThousandEyes API and should be installed before using any of the published SDKs.
|
||||||
|
|
||||||
`PaginatorIterator` is unbounded, so wrap it with `itertools.islice` to cap the number of items and avoid making unintended, potentially expensive API calls.
|
Usage example for iterating paginated responses:
|
||||||
Pick a slice size that matches your UI or batch size so you only fetch what you plan to process:
|
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from thousandeyes_sdk.core import Configuration, ApiClient, PaginatorIterator
|
from thousandeyes_sdk.core import PaginatorIterator
|
||||||
from thousandeyes_sdk.dashboards import DashboardsApi
|
from thousandeyes_sdk.dashboards.api.dashboards_api import DashboardsApi
|
||||||
from itertools import islice
|
|
||||||
|
|
||||||
configuration = Configuration(
|
dashboards_api = DashboardsApi()
|
||||||
host = "https://api.thousandeyes.com/v7",
|
for widget_data in PaginatorIterator(
|
||||||
access_token = "an_access_token",
|
dashboards_api.get_dashboard_widget_data,
|
||||||
)
|
lambda response: response.data.tests if response.data else [],
|
||||||
|
dashboard_id="dashboard-id",
|
||||||
|
widget_id="widget-id",
|
||||||
def get_dashboard_widget_data():
|
):
|
||||||
with ApiClient(configuration) as client:
|
print(widget_data)
|
||||||
dashboards_api = DashboardsApi(client)
|
|
||||||
for item in list(islice(PaginatorIterator(
|
|
||||||
dashboards_api.get_dashboard_widget_data,
|
|
||||||
lambda response: response.data.tests,
|
|
||||||
dashboard_id="a_dashboard_id",
|
|
||||||
widget_id="a_widget_id",
|
|
||||||
), 20)):
|
|
||||||
print(item.test_id)
|
|
||||||
```
|
```
|
||||||
|
|||||||
@ -60,8 +60,7 @@ class PaginatorIterator(Generic[P, R, I]):
|
|||||||
|
|
||||||
while True:
|
while True:
|
||||||
response = self._method(**params)
|
response = self._method(**params)
|
||||||
items = self._items_getter(response)
|
for item in self._items_getter(response):
|
||||||
for item in items if items else []:
|
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
next_cursor = self._next_cursor_from_response(response)
|
next_cursor = self._next_cursor_from_response(response)
|
||||||
@ -72,10 +71,14 @@ class PaginatorIterator(Generic[P, R, I]):
|
|||||||
last_cursor = next_cursor
|
last_cursor = next_cursor
|
||||||
|
|
||||||
def _next_cursor_from_response(self, response: Any) -> Optional[str]:
|
def _next_cursor_from_response(self, response: Any) -> Optional[str]:
|
||||||
links = getattr(response, "links", None)
|
data = getattr(response, "data", response)
|
||||||
|
links = getattr(data, "links", None)
|
||||||
|
|
||||||
if links is None:
|
if links is None:
|
||||||
links = getattr(response, "_links", None)
|
links = getattr(data, "_links", None)
|
||||||
|
|
||||||
|
if links is None and isinstance(data, Mapping):
|
||||||
|
links = data.get("_links") or data.get("links")
|
||||||
|
|
||||||
if links is None:
|
if links is None:
|
||||||
return None
|
return None
|
||||||
|
|||||||
@ -14,7 +14,8 @@ def test_iterator_uses_cursor_from_next_href():
|
|||||||
else:
|
else:
|
||||||
links = SimpleNamespace(next=None)
|
links = SimpleNamespace(next=None)
|
||||||
items = ["third"]
|
items = ["third"]
|
||||||
return SimpleNamespace(links=links, items=items)
|
data = SimpleNamespace(links=links)
|
||||||
|
return SimpleNamespace(data=data, items=items)
|
||||||
|
|
||||||
responses = list(PaginatorIterator(method, lambda response: response.items))
|
responses = list(PaginatorIterator(method, lambda response: response.items))
|
||||||
|
|
||||||
@ -28,12 +29,12 @@ def test_iterator_reads_cursor_from_links_mapping():
|
|||||||
def method(**params):
|
def method(**params):
|
||||||
calls.append(params.copy())
|
calls.append(params.copy())
|
||||||
if params.get("pageCursor") is None:
|
if params.get("pageCursor") is None:
|
||||||
links = {"next": {"href": "https://example.com?foo=1&pageCursor=xyz"}}
|
data = {"_links": {"next": {"href": "https://example.com?foo=1&pageCursor=xyz"}}}
|
||||||
items = ["alpha"]
|
items = ["alpha"]
|
||||||
else:
|
else:
|
||||||
links = {"next": None}
|
data = {"_links": {"next": None}}
|
||||||
items = ["beta"]
|
items = ["beta"]
|
||||||
return SimpleNamespace(links=links, items=items)
|
return SimpleNamespace(data=data, items=items)
|
||||||
|
|
||||||
responses = list(PaginatorIterator(method, lambda response: response.items, cursor_param="pageCursor"))
|
responses = list(PaginatorIterator(method, lambda response: response.items, cursor_param="pageCursor"))
|
||||||
|
|
||||||
@ -47,12 +48,12 @@ def test_iterator_stops_when_no_cursor_param_present():
|
|||||||
def method(**params):
|
def method(**params):
|
||||||
calls.append(params.copy())
|
calls.append(params.copy())
|
||||||
if params.get("cursor") is None:
|
if params.get("cursor") is None:
|
||||||
links = {"next": "/next/page"}
|
data = {"links": {"next": "/next/page"}}
|
||||||
items = ["one"]
|
items = ["one"]
|
||||||
else:
|
else:
|
||||||
links = {"next": None}
|
data = {"links": {"next": None}}
|
||||||
items = ["two"]
|
items = ["two"]
|
||||||
return SimpleNamespace(links=links, items=items)
|
return SimpleNamespace(data=data, items=items)
|
||||||
|
|
||||||
responses = list(PaginatorIterator(method, lambda response: response.items))
|
responses = list(PaginatorIterator(method, lambda response: response.items))
|
||||||
|
|
||||||
@ -65,8 +66,8 @@ def test_iterator_stops_on_repeated_cursor():
|
|||||||
|
|
||||||
def method(**params):
|
def method(**params):
|
||||||
calls.append(params.copy())
|
calls.append(params.copy())
|
||||||
links = {"next": "https://example.com?cursor=same"}
|
data = {"links": {"next": "https://example.com?cursor=same"}}
|
||||||
return SimpleNamespace(links=links, items=["only"])
|
return SimpleNamespace(data=data, items=["only"])
|
||||||
|
|
||||||
responses = list(PaginatorIterator(method, lambda response: response.items, cursor="same"))
|
responses = list(PaginatorIterator(method, lambda response: response.items, cursor="same"))
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user