Skip to content

Commit 15953e7

Browse files
committed
@pcrespov use old implementation of pagination generator
1 parent d1a8df8 commit 15953e7

File tree

6 files changed

+42
-52
lines changed

6 files changed

+42
-52
lines changed

clients/python/src/osparc/_api_files_api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import shutil
3232
from ._utils import (
3333
DEFAULT_TIMEOUT_SECONDS,
34-
PaginationIterator,
34+
PaginationIterable,
3535
compute_sha256,
3636
file_chunk_generator,
3737
Chunk,
@@ -273,7 +273,7 @@ def _search_files(
273273
file_id: Optional[str] = None,
274274
sha256_checksum: Optional[str] = None,
275275
timeout_seconds: int = DEFAULT_TIMEOUT_SECONDS,
276-
) -> PaginationIterator:
276+
) -> PaginationIterable:
277277
kwargs = {
278278
"file_id": file_id,
279279
"sha256_checksum": sha256_checksum,
@@ -285,7 +285,7 @@ def _pagination_method():
285285
**{k: v for k, v in kwargs.items() if v is not None}
286286
)
287287

288-
return PaginationIterator(
288+
return PaginationIterable(
289289
first_page_callback=_pagination_method,
290290
api_client=self.api_client,
291291
base_url=self.api_client.configuration.host,

clients/python/src/osparc/_api_solvers_api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from ._utils import (
1212
_DEFAULT_PAGINATION_LIMIT,
1313
_DEFAULT_PAGINATION_OFFSET,
14-
PaginationIterator,
14+
PaginationIterable,
1515
)
1616

1717
import warnings
@@ -47,7 +47,7 @@ def list_solver_ports(
4747
)
4848
return page.items if page.items else []
4949

50-
def iter_jobs(self, solver_key: str, version: str, **kwargs) -> PaginationIterator:
50+
def iter_jobs(self, solver_key: str, version: str, **kwargs) -> PaginationIterable:
5151
"""Returns an iterator through which one can iterate over
5252
all Jobs submitted to the solver
5353
@@ -72,14 +72,14 @@ def _pagination_method():
7272
**kwargs,
7373
)
7474

75-
return PaginationIterator(
75+
return PaginationIterable(
7676
first_page_callback=_pagination_method,
7777
api_client=self.api_client,
7878
base_url=self.api_client.configuration.host,
7979
auth=self._auth,
8080
)
8181

82-
def jobs(self, solver_key: str, version: str, **kwargs) -> PaginationIterator:
82+
def jobs(self, solver_key: str, version: str, **kwargs) -> PaginationIterable:
8383
warnings.warn(
8484
"The 'jobs' method is deprecated and will be removed in a future version. "
8585
"Please use 'iter_jobs' instead.",

clients/python/src/osparc/_api_studies_api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from ._utils import (
1818
_DEFAULT_PAGINATION_LIMIT,
1919
_DEFAULT_PAGINATION_OFFSET,
20-
PaginationIterator,
20+
PaginationIterable,
2121
)
2222
import warnings
2323

@@ -65,7 +65,7 @@ def clone_study(self, study_id: str, **kwargs):
6565
kwargs = {**kwargs, **ParentProjectInfo().model_dump(exclude_none=True)}
6666
return super().clone_study(study_id, **kwargs)
6767

68-
def iter_studies(self, **kwargs) -> PaginationIterator:
68+
def iter_studies(self, **kwargs) -> PaginationIterable:
6969
def _pagination_method():
7070
page_study = self.list_studies(
7171
limit=_DEFAULT_PAGINATION_LIMIT,
@@ -75,14 +75,14 @@ def _pagination_method():
7575
assert isinstance(page_study, PageStudy) # nosec
7676
return page_study
7777

78-
return PaginationIterator(
78+
return PaginationIterable(
7979
first_page_callback=_pagination_method,
8080
api_client=self.api_client,
8181
base_url=self.api_client.configuration.host,
8282
auth=self._auth,
8383
)
8484

85-
def studies(self, **kwargs) -> PaginationIterator:
85+
def studies(self, **kwargs) -> PaginationIterable:
8686
warnings.warn(
8787
"The 'studies' method is deprecated and will be removed in a future version. "
8888
"Please use 'iter_studies' instead.",

clients/python/src/osparc/_utils.py

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
Optional,
88
TypeVar,
99
Union,
10-
cast,
11-
List,
1210
NamedTuple,
1311
)
14-
from collections.abc import Iterator
12+
from collections.abc import Iterable, Generator, Sized
1513
import httpx
1614
from osparc_client import (
1715
ApiClient,
@@ -24,6 +22,7 @@
2422
Study,
2523
)
2624
import aiofiles
25+
from .exceptions import RequestError
2726

2827
_KB = 1024 # in bytes
2928
_MB = _KB * 1024 # in bytes
@@ -38,7 +37,7 @@
3837
T = TypeVar("T", Job, File, Solver, Study)
3938

4039

41-
class PaginationIterator(Iterator):
40+
class PaginationIterable(Iterable, Sized):
4241
"""Class for wrapping paginated http methods as iterables. It supports three simple operations:
4342
- for elm in pagination_iterable
4443
- elm = next(pagination_iterable)
@@ -53,46 +52,37 @@ def __init__(
5352
):
5453
self._first_page_callback: Callable[[], Page] = first_page_callback
5554
self._api_client: ApiClient = api_client
55+
self._next_page_url: Optional[str] = None
5656
self._client: httpx.Client = httpx.Client(
5757
auth=auth, base_url=base_url, follow_redirects=True
5858
)
59-
self._page: Optional[Page] = None
60-
self._items_iterator: Optional[Iterator] = None
6159

6260
def __del__(self):
6361
self._client.close()
6462

65-
def __next__(self):
66-
if self._page is None:
67-
self._page = self._first_page_callback()
68-
self._items_iterator = iter(cast(List, self._page.items))
69-
if self._items_iterator is None:
70-
raise StopIteration
71-
assert self._items_iterator is not None # nosec
72-
try:
73-
return next(self._items_iterator)
74-
except StopIteration as exc:
75-
next_page_url = self._page.links.next
76-
if next_page_url is None:
77-
self._page = None
78-
self._items_iterator = None
79-
raise StopIteration from exc
80-
response = self._client.get(next_page_url)
81-
self._page = self._api_client._ApiClient__deserialize(
82-
response.json(), type(self._page)
83-
)
84-
assert self._page is not None # nosec
85-
self._items_iterator = iter(cast(List, self._page.items))
86-
return next(self._items_iterator)
87-
8863
def __len__(self) -> int:
8964
"""Number of elements which the iterator can produce"""
90-
if self._page is not None:
91-
return cast(int, self._page.total)
92-
self._page = self._first_page_callback()
93-
assert self._page is not None # nosec
94-
self._items_iterator = iter(cast(List, self._page.items))
95-
return cast(int, self._page.total)
65+
page: Page = self._first_page_callback()
66+
assert isinstance(page.total, int)
67+
return page.total
68+
69+
def __iter__(self) -> Generator[T, None, None]:
70+
"""Returns the generator"""
71+
if len(self) == 0:
72+
return
73+
page: Page = self._first_page_callback()
74+
while True:
75+
assert page.items is not None
76+
assert isinstance(page.total, int)
77+
yield from page.items
78+
if page.links.next is None:
79+
return
80+
response: httpx.Response = self._client.get(page.links.next)
81+
try:
82+
response.raise_for_status()
83+
except httpx.HTTPStatusError as e:
84+
raise RequestError(f"{e}") from e
85+
page = self._api_client._ApiClient__deserialize(response.json(), type(page))
9686

9787

9888
class Chunk(NamedTuple):

clients/python/test/e2e/test_files_api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pathlib import Path
99

1010
import osparc
11-
from osparc._utils import PaginationIterator
11+
from osparc._utils import PaginationIterable
1212
import pytest
1313
from memory_profiler import memory_usage
1414
from typing import Final, Callable
@@ -90,7 +90,7 @@ def test_search_files(
9090
use_id: bool,
9191
faker: Faker,
9292
) -> None:
93-
results: PaginationIterator = files_api._search_files(
93+
results: PaginationIterable = files_api._search_files(
9494
sha256_checksum=f"{faker.sha256()}"
9595
)
9696
assert len(results) == 0, "Found file which shouldn't be there"
@@ -102,5 +102,5 @@ def test_search_files(
102102
else None,
103103
)
104104
assert len(results) == 1, "Could not find file after it had been uploaded"
105-
file = next(results)
105+
file = next(iter(results))
106106
assert file.checksum == large_server_file.server_file.checksum

clients/python/test/test_osparc/test_basic.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from faker import Faker
1313
import httpx
1414
from urllib.parse import urlparse
15-
from osparc._utils import PaginationIterator
15+
from osparc._utils import PaginationIterable
1616
from functools import partial
1717
from copy import deepcopy
1818

@@ -124,14 +124,14 @@ def _sideeffect(all_items: List, request: httpx.Request):
124124
side_effect=partial(_sideeffect, server_items)
125125
)
126126

127-
pagination_iterator = PaginationIterator(
127+
pagination_iterator = PaginationIterable(
128128
lambda: page_file, api_client=api_client, base_url=_base_url, auth=_auth
129129
)
130130
client_items = [item for item in pagination_iterator]
131131
assert len(server_items) > 0
132132
assert server_items == client_items
133133

134-
first_client_item = next(pagination_iterator)
134+
first_client_item = next(iter(pagination_iterator))
135135
assert first_client_item == server_items[0]
136136

137137
assert len(pagination_iterator) == page_file.total

0 commit comments

Comments
 (0)