Skip to content

Commit a6af14d

Browse files
committed
feat: add pagination methods for querying VNDB user lists and enhance example usage
1 parent 5c76c80 commit a6af14d

File tree

3 files changed

+502
-10
lines changed

3 files changed

+502
-10
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,5 @@ cython_debug/
166166
Thumbs.db
167167

168168
# Node modules (if any)
169-
node_modules/
169+
node_modules/
170+
VNDB_API.htm

src/veedb/client.py

Lines changed: 169 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
22
import aiohttp
33
import logging
4-
from typing import List, Optional, Union, TypeVar, Type, Dict, Any, Generic
4+
from typing import List, Optional, Union, TypeVar, Type, Dict, Any, Generic, AsyncGenerator
55

66
from .methods.fetch import _fetch_api
77
from .apitypes.common import (
@@ -114,14 +114,92 @@ async def query(
114114
query_options.fields = "id"
115115
return await self._post_query(query_options)
116116

117-
async def validate_filters(self, filters: Union[List, str, None]) -> Dict[str, Any]:
118-
"""Validates filters against the schema for this specific endpoint."""
119-
return await self._client.validate_filters(self._endpoint_path, filters)
120-
121-
async def get_available_fields(self) -> List[str]:
122-
"""Gets all available filterable fields for this endpoint."""
123-
return await self._client.get_available_fields(self._endpoint_path)
124-
117+
async def query_all_pages(
118+
self, query_options: QueryRequest = QueryRequest(), max_pages: Optional[int] = None
119+
) -> List[T_QueryItem]:
120+
"""
121+
Fetch all results across multiple pages automatically.
122+
123+
Args:
124+
query_options: The query to execute
125+
max_pages: Maximum number of pages to fetch (None for unlimited)
126+
127+
Returns:
128+
List of all results from all pages
129+
"""
130+
if not query_options.fields:
131+
query_options.fields = "id"
132+
133+
all_results = []
134+
page_number = 1
135+
136+
while True:
137+
# Create a copy of the query options with the current page number
138+
current_query = QueryRequest(
139+
filters=query_options.filters,
140+
fields=query_options.fields,
141+
sort=query_options.sort,
142+
reverse=query_options.reverse,
143+
results=query_options.results,
144+
page=page_number,
145+
user=query_options.user,
146+
count=query_options.count,
147+
compact_filters=query_options.compact_filters,
148+
normalized_filters=query_options.normalized_filters,
149+
)
150+
151+
response = await self._post_query(current_query)
152+
all_results.extend(response.results)
153+
154+
if not response.more:
155+
break
156+
157+
if max_pages and page_number >= max_pages:
158+
break
159+
160+
page_number += 1
161+
162+
return all_results
163+
164+
async def query_paginated(
165+
self, query_options: QueryRequest = QueryRequest()
166+
) -> AsyncGenerator[QueryResponse[T_QueryItem], None]:
167+
"""
168+
Generator that yields query responses page by page.
169+
170+
Args:
171+
query_options: The query to execute
172+
173+
Yields:
174+
QueryResponse objects for each page
175+
"""
176+
if not query_options.fields:
177+
query_options.fields = "id"
178+
179+
page_number = 1
180+
181+
while True:
182+
# Create a copy of the query options with the current page number
183+
current_query = QueryRequest(
184+
filters=query_options.filters,
185+
fields=query_options.fields,
186+
sort=query_options.sort,
187+
reverse=query_options.reverse,
188+
results=query_options.results,
189+
page=page_number,
190+
user=query_options.user,
191+
count=query_options.count,
192+
compact_filters=query_options.compact_filters,
193+
normalized_filters=query_options.normalized_filters,
194+
)
195+
196+
response = await self._post_query(current_query)
197+
yield response
198+
199+
if not response.more:
200+
break
201+
202+
page_number += 1
125203

126204
class _VNClient(_BaseEntityClient[VN, VN]):
127205
def __init__(self, client: "VNDB"):
@@ -229,6 +307,88 @@ async def delete_entry(self, vn_id: VNDBID) -> None:
229307
session = self._client._get_session()
230308
await _fetch_api(session=session, method="DELETE", url=url, token=self._client.api_token)
231309

310+
async def query_all_pages(
311+
self, user_id: VNDBID, query_options: QueryRequest = QueryRequest(), max_pages: Optional[int] = None
312+
) -> List[UlistItem]:
313+
"""
314+
Fetch all ulist results across multiple pages automatically.
315+
316+
Args:
317+
user_id: The user ID to query
318+
query_options: The query to execute
319+
max_pages: Maximum number of pages to fetch (None for unlimited)
320+
321+
Returns:
322+
List of all results from all pages
323+
"""
324+
all_results = []
325+
page_number = 1
326+
327+
while True:
328+
# Create a copy of the query options with the current page number
329+
current_query = QueryRequest(
330+
filters=query_options.filters,
331+
fields=query_options.fields,
332+
sort=query_options.sort,
333+
reverse=query_options.reverse,
334+
results=query_options.results,
335+
page=page_number,
336+
user=query_options.user,
337+
count=query_options.count,
338+
compact_filters=query_options.compact_filters,
339+
normalized_filters=query_options.normalized_filters,
340+
)
341+
342+
response = await self.query(user_id, current_query)
343+
all_results.extend(response.results)
344+
345+
if not response.more:
346+
break
347+
348+
if max_pages and page_number >= max_pages:
349+
break
350+
351+
page_number += 1
352+
353+
return all_results
354+
355+
async def query_paginated(
356+
self, user_id: VNDBID, query_options: QueryRequest = QueryRequest()
357+
) -> AsyncGenerator[QueryResponse[UlistItem], None]:
358+
"""
359+
Generator that yields ulist query responses page by page.
360+
361+
Args:
362+
user_id: The user ID to query
363+
query_options: The query to execute
364+
365+
Yields:
366+
QueryResponse objects for each page
367+
"""
368+
page_number = 1
369+
370+
while True:
371+
# Create a copy of the query options with the current page number
372+
current_query = QueryRequest(
373+
filters=query_options.filters,
374+
fields=query_options.fields,
375+
sort=query_options.sort,
376+
reverse=query_options.reverse,
377+
results=query_options.results,
378+
page=page_number,
379+
user=query_options.user,
380+
count=query_options.count,
381+
compact_filters=query_options.compact_filters,
382+
normalized_filters=query_options.normalized_filters,
383+
)
384+
385+
response = await self.query(user_id, current_query)
386+
yield response
387+
388+
if not response.more:
389+
break
390+
391+
page_number += 1
232392

233393
class _RlistClient:
234394
def __init__(self, client: "VNDB"):

0 commit comments

Comments
 (0)