valentina-python-client 2.4.1__tar.gz → 2.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/PKG-INFO +1 -1
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/pyproject.toml +1 -1
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/__init__.py +1 -1
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/base.py +47 -12
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/character_blueprint.py +38 -3
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/dictionary.py +6 -2
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/constants.py +3 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/base.py +43 -9
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/character_blueprint.py +25 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/dictionary.py +4 -2
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/LICENSE +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/README.md +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_codegen.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/__init__.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/client.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/registry.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/__init__.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/_audit_params.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/campaign_book_chapters.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/campaign_books.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/campaigns.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/character_autogen.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/character_traits.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/characters.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/companies.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/developers.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/dicerolls.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/global_admin.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/options.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/system.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/user_lookup.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/user_self_registration.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/users.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/testing/__init__.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/testing/_client.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/client.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/config.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/endpoints.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/exceptions.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/__init__.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/audit_logs.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/books.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/campaigns.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/chapters.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/character_autogen.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/character_blueprint.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/character_trait.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/characters.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/companies.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/developers.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/diceroll.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/dictionary.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/full_sheet.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/global_admin.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/pagination.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/shared.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/system.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/user_lookup.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/users.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/py.typed +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/registry.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/__init__.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/_audit_params.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/campaign_book_chapters.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/campaign_books.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/campaigns.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/character_autogen.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/character_traits.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/characters.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/companies.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/developers.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/dicerolls.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/global_admin.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/options.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/system.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/user_lookup.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/user_self_registration.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/users.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/__init__.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_client.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_factories.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_router.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_routes.py +0 -0
- {valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/validate_constants.py +0 -0
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/base.py
RENAMED
|
@@ -168,7 +168,7 @@ class SyncBaseService:
|
|
|
168
168
|
config = self._client._config
|
|
169
169
|
max_attempts = config.max_retries + 1 if config.auto_retry_rate_limit else 1
|
|
170
170
|
retry_statuses = config.retry_statuses
|
|
171
|
-
request_logger = logger.bind(method=method, url=path)
|
|
171
|
+
request_logger = logger.bind(method=method, url=path, params=params)
|
|
172
172
|
request_logger.trace("Send request")
|
|
173
173
|
last_error: RateLimitError | ServerError | None = None
|
|
174
174
|
for attempt in range(max_attempts):
|
|
@@ -196,7 +196,7 @@ class SyncBaseService:
|
|
|
196
196
|
time.sleep(delay)
|
|
197
197
|
continue
|
|
198
198
|
try:
|
|
199
|
-
self._raise_for_status(response, method, path)
|
|
199
|
+
self._raise_for_status(response, method, path, params=params)
|
|
200
200
|
self._log_success_response(response, request_logger)
|
|
201
201
|
return response
|
|
202
202
|
except RateLimitError as e:
|
|
@@ -260,13 +260,17 @@ class SyncBaseService:
|
|
|
260
260
|
if header_id:
|
|
261
261
|
response_data["request_id"] = header_id
|
|
262
262
|
|
|
263
|
-
def _raise_for_status(
|
|
263
|
+
def _raise_for_status(
|
|
264
|
+
self, response: httpx.Response, method: str, url: str, params: dict[str, Any] | None = None
|
|
265
|
+
) -> None:
|
|
264
266
|
"""Raise appropriate exception for error responses.
|
|
265
267
|
|
|
266
268
|
Args:
|
|
267
269
|
response: The HTTP response to check.
|
|
268
270
|
method: The HTTP method of the request.
|
|
269
271
|
url: The URL path of the request.
|
|
272
|
+
params: The query parameters of the request, logged to disambiguate
|
|
273
|
+
paginated calls that share the same path.
|
|
270
274
|
|
|
271
275
|
Raises:
|
|
272
276
|
AuthenticationError: For 401 responses.
|
|
@@ -289,7 +293,11 @@ class SyncBaseService:
|
|
|
289
293
|
message = response.text or f"HTTP {status_code}"
|
|
290
294
|
self._inject_request_id_fallback(response_data, response)
|
|
291
295
|
error_logger = logger.bind(
|
|
292
|
-
method=method,
|
|
296
|
+
method=method,
|
|
297
|
+
url=url,
|
|
298
|
+
params=params,
|
|
299
|
+
status=status_code,
|
|
300
|
+
request_id=response_data.get("request_id"),
|
|
293
301
|
)
|
|
294
302
|
if status_code == 429:
|
|
295
303
|
retry_after = self._parse_retry_after(response)
|
|
@@ -584,20 +592,23 @@ class SyncBaseService:
|
|
|
584
592
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
585
593
|
offset: int = 0,
|
|
586
594
|
params: dict[str, Any] | None = None,
|
|
595
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
587
596
|
) -> PaginatedResponse[dict[str, Any]]:
|
|
588
597
|
"""Make a paginated GET request.
|
|
589
598
|
|
|
590
599
|
Args:
|
|
591
600
|
path: API endpoint path.
|
|
592
|
-
limit: Maximum number of items to return (
|
|
601
|
+
limit: Maximum number of items to return (default 10).
|
|
593
602
|
offset: Number of items to skip from the beginning (default 0).
|
|
594
603
|
params: Additional query parameters.
|
|
604
|
+
max_limit: Upper bound the limit is clamped to (default 100). Reference/catalog
|
|
605
|
+
endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
595
606
|
|
|
596
607
|
Returns:
|
|
597
608
|
A PaginatedResponse containing the items and pagination metadata.
|
|
598
609
|
"""
|
|
599
610
|
request_params = {
|
|
600
|
-
"limit": min(max(limit, 0),
|
|
611
|
+
"limit": min(max(limit, 0), max_limit),
|
|
601
612
|
"offset": max(offset, 0),
|
|
602
613
|
**(params or {}),
|
|
603
614
|
}
|
|
@@ -612,20 +623,25 @@ class SyncBaseService:
|
|
|
612
623
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
613
624
|
offset: int = 0,
|
|
614
625
|
params: dict[str, Any] | None = None,
|
|
626
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
615
627
|
) -> PaginatedResponse[T]:
|
|
616
628
|
"""Make a paginated GET request and parse items into the given model class.
|
|
617
629
|
|
|
618
630
|
Args:
|
|
619
631
|
path: API endpoint path.
|
|
620
632
|
model_class: Pydantic model class to validate each item into.
|
|
621
|
-
limit: Maximum number of items to return (
|
|
633
|
+
limit: Maximum number of items to return (default 10).
|
|
622
634
|
offset: Number of items to skip from the beginning (default 0).
|
|
623
635
|
params: Additional query parameters.
|
|
636
|
+
max_limit: Upper bound the limit is clamped to (default 100). Reference/catalog
|
|
637
|
+
endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
624
638
|
|
|
625
639
|
Returns:
|
|
626
640
|
A PaginatedResponse containing validated model instances.
|
|
627
641
|
"""
|
|
628
|
-
response = self._get_paginated(
|
|
642
|
+
response = self._get_paginated(
|
|
643
|
+
path, limit=limit, offset=offset, params=params, max_limit=max_limit
|
|
644
|
+
)
|
|
629
645
|
return PaginatedResponse(
|
|
630
646
|
items=[model_class.model_validate(item) for item in response.items],
|
|
631
647
|
limit=response.limit,
|
|
@@ -634,7 +650,12 @@ class SyncBaseService:
|
|
|
634
650
|
)
|
|
635
651
|
|
|
636
652
|
def _iter_all_pages(
|
|
637
|
-
self,
|
|
653
|
+
self,
|
|
654
|
+
path: str,
|
|
655
|
+
*,
|
|
656
|
+
limit: int = MAX_PAGE_LIMIT,
|
|
657
|
+
params: dict[str, Any] | None = None,
|
|
658
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
638
659
|
) -> Iterator[dict[str, Any]]:
|
|
639
660
|
"""Iterate through all pages of a paginated endpoint.
|
|
640
661
|
|
|
@@ -645,6 +666,8 @@ class SyncBaseService:
|
|
|
645
666
|
path: API endpoint path.
|
|
646
667
|
limit: Items per page (default 100 for efficiency).
|
|
647
668
|
params: Additional query parameters.
|
|
669
|
+
max_limit: Upper bound the per-page limit is clamped to (default 100).
|
|
670
|
+
Reference/catalog endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
648
671
|
|
|
649
672
|
Yields:
|
|
650
673
|
Individual items from the paginated response.
|
|
@@ -657,7 +680,9 @@ class SyncBaseService:
|
|
|
657
680
|
"""
|
|
658
681
|
offset = 0
|
|
659
682
|
while True:
|
|
660
|
-
page = self._get_paginated(
|
|
683
|
+
page = self._get_paginated(
|
|
684
|
+
path, limit=limit, offset=offset, params=params, max_limit=max_limit
|
|
685
|
+
)
|
|
661
686
|
for item in page.items:
|
|
662
687
|
yield item
|
|
663
688
|
if not page.has_more:
|
|
@@ -665,7 +690,12 @@ class SyncBaseService:
|
|
|
665
690
|
offset = page.next_offset
|
|
666
691
|
|
|
667
692
|
def _get_all(
|
|
668
|
-
self,
|
|
693
|
+
self,
|
|
694
|
+
path: str,
|
|
695
|
+
*,
|
|
696
|
+
limit: int = MAX_PAGE_LIMIT,
|
|
697
|
+
params: dict[str, Any] | None = None,
|
|
698
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
669
699
|
) -> list[dict[str, Any]]:
|
|
670
700
|
"""Fetch all items from a paginated endpoint.
|
|
671
701
|
|
|
@@ -677,8 +707,13 @@ class SyncBaseService:
|
|
|
677
707
|
path: API endpoint path.
|
|
678
708
|
limit: Items per page (default 100 for efficiency).
|
|
679
709
|
params: Additional query parameters.
|
|
710
|
+
max_limit: Upper bound the per-page limit is clamped to (default 100).
|
|
711
|
+
Reference/catalog endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
680
712
|
|
|
681
713
|
Returns:
|
|
682
714
|
A list of all items from all pages.
|
|
683
715
|
"""
|
|
684
|
-
return [
|
|
716
|
+
return [
|
|
717
|
+
item
|
|
718
|
+
for item in self._iter_all_pages(path, limit=limit, params=params, max_limit=max_limit)
|
|
719
|
+
]
|
|
@@ -5,7 +5,13 @@ from collections.abc import Iterator
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from vclient._sync.services.base import SyncBaseService
|
|
8
|
-
from vclient.constants import
|
|
8
|
+
from vclient.constants import (
|
|
9
|
+
DEFAULT_PAGE_LIMIT,
|
|
10
|
+
MAX_REFERENCE_PAGE_LIMIT,
|
|
11
|
+
BlueprintTraitOrderBy,
|
|
12
|
+
CharacterClass,
|
|
13
|
+
GameVersion,
|
|
14
|
+
)
|
|
9
15
|
from vclient.endpoints import Endpoints
|
|
10
16
|
from vclient.models import (
|
|
11
17
|
CharacterConcept,
|
|
@@ -58,6 +64,7 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
58
64
|
SheetSection,
|
|
59
65
|
limit=limit,
|
|
60
66
|
offset=offset,
|
|
67
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
61
68
|
params=self._build_params(game_version=game_version, character_class=character_class),
|
|
62
69
|
)
|
|
63
70
|
|
|
@@ -84,6 +91,8 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
84
91
|
"""Iterate through all character blueprint sections."""
|
|
85
92
|
for section in self._iter_all_pages(
|
|
86
93
|
self._format_endpoint(Endpoints.BLUEPRINT_SECTIONS),
|
|
94
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
95
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
87
96
|
params=self._build_params(game_version=game_version, character_class=character_class),
|
|
88
97
|
):
|
|
89
98
|
yield SheetSection.model_validate(section)
|
|
@@ -110,6 +119,7 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
110
119
|
TraitCategory,
|
|
111
120
|
limit=limit,
|
|
112
121
|
offset=offset,
|
|
122
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
113
123
|
params=self._build_params(
|
|
114
124
|
game_version=game_version, section_id=section_id, character_class=character_class
|
|
115
125
|
),
|
|
@@ -140,6 +150,8 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
140
150
|
"""Iterate through all character blueprint categories."""
|
|
141
151
|
for category in self._iter_all_pages(
|
|
142
152
|
self._format_endpoint(Endpoints.BLUEPRINT_CATEGORIES),
|
|
153
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
154
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
143
155
|
params=self._build_params(
|
|
144
156
|
game_version=game_version, section_id=section_id, character_class=character_class
|
|
145
157
|
),
|
|
@@ -168,6 +180,7 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
168
180
|
TraitSubcategory,
|
|
169
181
|
limit=limit,
|
|
170
182
|
offset=offset,
|
|
183
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
171
184
|
params=self._build_params(
|
|
172
185
|
game_version=game_version, category_id=category_id, character_class=character_class
|
|
173
186
|
),
|
|
@@ -198,6 +211,8 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
198
211
|
"""Iterate through all character blueprint subcategories."""
|
|
199
212
|
for subcategory in self._iter_all_pages(
|
|
200
213
|
self._format_endpoint(Endpoints.BLUEPRINT_SUBCATEGORIES),
|
|
214
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
215
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
201
216
|
params=self._build_params(
|
|
202
217
|
game_version=game_version, category_id=category_id, character_class=character_class
|
|
203
218
|
),
|
|
@@ -232,6 +247,7 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
232
247
|
Trait,
|
|
233
248
|
limit=limit,
|
|
234
249
|
offset=offset,
|
|
250
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
235
251
|
params=self._build_params(
|
|
236
252
|
character_class=character_class,
|
|
237
253
|
category_id=category_id,
|
|
@@ -282,6 +298,8 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
282
298
|
"""Iterate through all character blueprint traits."""
|
|
283
299
|
for trait in self._iter_all_pages(
|
|
284
300
|
self._format_endpoint(Endpoints.BLUEPRINT_TRAITS),
|
|
301
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
302
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
285
303
|
params=self._build_params(
|
|
286
304
|
character_class=character_class,
|
|
287
305
|
category_id=category_id,
|
|
@@ -306,7 +324,11 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
306
324
|
) -> PaginatedResponse[CharacterConcept]:
|
|
307
325
|
"""Get a paginated page of character concepts."""
|
|
308
326
|
return self._get_paginated_as(
|
|
309
|
-
self._format_endpoint(Endpoints.CONCEPTS),
|
|
327
|
+
self._format_endpoint(Endpoints.CONCEPTS),
|
|
328
|
+
CharacterConcept,
|
|
329
|
+
limit=limit,
|
|
330
|
+
offset=offset,
|
|
331
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
310
332
|
)
|
|
311
333
|
|
|
312
334
|
def list_all_concepts(self) -> list[CharacterConcept]:
|
|
@@ -315,7 +337,11 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
315
337
|
|
|
316
338
|
def iter_all_concepts(self) -> Iterator[CharacterConcept]:
|
|
317
339
|
"""Iterate through all character concepts."""
|
|
318
|
-
for concept in self._iter_all_pages(
|
|
340
|
+
for concept in self._iter_all_pages(
|
|
341
|
+
self._format_endpoint(Endpoints.CONCEPTS),
|
|
342
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
343
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
344
|
+
):
|
|
319
345
|
yield CharacterConcept.model_validate(concept)
|
|
320
346
|
|
|
321
347
|
def get_concept(self, *, concept_id: str) -> CharacterConcept:
|
|
@@ -336,6 +362,7 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
336
362
|
VampireClan,
|
|
337
363
|
limit=limit,
|
|
338
364
|
offset=offset,
|
|
365
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
339
366
|
params=self._build_params(game_version=game_version),
|
|
340
367
|
)
|
|
341
368
|
|
|
@@ -351,6 +378,8 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
351
378
|
"""Iterate through all vampire clans."""
|
|
352
379
|
for clan in self._iter_all_pages(
|
|
353
380
|
self._format_endpoint(Endpoints.VAMPIRE_CLANS),
|
|
381
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
382
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
354
383
|
params=self._build_params(game_version=game_version),
|
|
355
384
|
):
|
|
356
385
|
yield VampireClan.model_validate(clan)
|
|
@@ -375,6 +404,7 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
375
404
|
WerewolfAuspice,
|
|
376
405
|
limit=limit,
|
|
377
406
|
offset=offset,
|
|
407
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
378
408
|
params=self._build_params(game_version=game_version),
|
|
379
409
|
)
|
|
380
410
|
|
|
@@ -390,6 +420,8 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
390
420
|
"""Iterate through all werewolf auspices."""
|
|
391
421
|
for auspice in self._iter_all_pages(
|
|
392
422
|
self._format_endpoint(Endpoints.WEREWOLF_AUSPICES),
|
|
423
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
424
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
393
425
|
params=self._build_params(game_version=game_version),
|
|
394
426
|
):
|
|
395
427
|
yield WerewolfAuspice.model_validate(auspice)
|
|
@@ -416,6 +448,7 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
416
448
|
WerewolfTribe,
|
|
417
449
|
limit=limit,
|
|
418
450
|
offset=offset,
|
|
451
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
419
452
|
params=self._build_params(game_version=game_version),
|
|
420
453
|
)
|
|
421
454
|
|
|
@@ -431,6 +464,8 @@ class SyncCharacterBlueprintService(SyncBaseService):
|
|
|
431
464
|
"""Iterate through all werewolf tribes."""
|
|
432
465
|
for tribe in self._iter_all_pages(
|
|
433
466
|
self._format_endpoint(Endpoints.WEREWOLF_TRIBES),
|
|
467
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
468
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
434
469
|
params=self._build_params(game_version=game_version),
|
|
435
470
|
):
|
|
436
471
|
yield WerewolfTribe.model_validate(tribe)
|
|
@@ -5,7 +5,7 @@ from collections.abc import Iterator
|
|
|
5
5
|
from typing import TYPE_CHECKING
|
|
6
6
|
|
|
7
7
|
from vclient._sync.services.base import SyncBaseService
|
|
8
|
-
from vclient.constants import DEFAULT_PAGE_LIMIT
|
|
8
|
+
from vclient.constants import DEFAULT_PAGE_LIMIT, MAX_REFERENCE_PAGE_LIMIT
|
|
9
9
|
from vclient.endpoints import Endpoints
|
|
10
10
|
from vclient.models import (
|
|
11
11
|
DictionaryTerm,
|
|
@@ -48,6 +48,7 @@ class SyncDictionaryService(SyncBaseService):
|
|
|
48
48
|
DictionaryTerm,
|
|
49
49
|
limit=limit,
|
|
50
50
|
offset=offset,
|
|
51
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
51
52
|
params=self._build_params(term=term),
|
|
52
53
|
)
|
|
53
54
|
|
|
@@ -55,11 +56,14 @@ class SyncDictionaryService(SyncBaseService):
|
|
|
55
56
|
"""Retrieve all dictionary terms."""
|
|
56
57
|
return [term for term in self.iter_all(term=term)]
|
|
57
58
|
|
|
58
|
-
def iter_all(
|
|
59
|
+
def iter_all(
|
|
60
|
+
self, *, term: str | None = None, limit: int = MAX_REFERENCE_PAGE_LIMIT
|
|
61
|
+
) -> Iterator[DictionaryTerm]:
|
|
59
62
|
"""Iterate through all dictionary terms."""
|
|
60
63
|
for item in self._iter_all_pages(
|
|
61
64
|
self._format_endpoint(Endpoints.DICTIONARY_TERMS),
|
|
62
65
|
limit=limit,
|
|
66
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
63
67
|
params=self._build_params(term=term),
|
|
64
68
|
):
|
|
65
69
|
yield DictionaryTerm.model_validate(item)
|
|
@@ -20,6 +20,9 @@ IDEMPOTENT_HTTP_METHODS: frozenset[str] = frozenset({"GET", "PUT", "DELETE"})
|
|
|
20
20
|
# Pagination defaults
|
|
21
21
|
DEFAULT_PAGE_LIMIT = 10
|
|
22
22
|
MAX_PAGE_LIMIT = 100
|
|
23
|
+
# Reference/catalog list endpoints serve bounded seed data and allow fetching a
|
|
24
|
+
# full catalog in one request, so they accept a higher per-request limit.
|
|
25
|
+
MAX_REFERENCE_PAGE_LIMIT = 1000
|
|
23
26
|
|
|
24
27
|
# Server log tail defaults
|
|
25
28
|
DEFAULT_LOG_TAIL_LIMIT = 100
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/base.py
RENAMED
|
@@ -176,7 +176,9 @@ class BaseService:
|
|
|
176
176
|
config = self._client._config # noqa: SLF001
|
|
177
177
|
max_attempts = config.max_retries + 1 if config.auto_retry_rate_limit else 1
|
|
178
178
|
retry_statuses = config.retry_statuses
|
|
179
|
-
|
|
179
|
+
# Bind params so paginated requests are distinguishable in logs; without
|
|
180
|
+
# limit/offset, identical paths look like duplicate (thundering-herd) calls.
|
|
181
|
+
request_logger = logger.bind(method=method, url=path, params=params)
|
|
180
182
|
|
|
181
183
|
# TRACE so the in-flight request is visible only when diagnosing hangs; the
|
|
182
184
|
# "Request complete" DEBUG line below is the superset record for normal use.
|
|
@@ -211,7 +213,7 @@ class BaseService:
|
|
|
211
213
|
continue
|
|
212
214
|
|
|
213
215
|
try:
|
|
214
|
-
self._raise_for_status(response, method, path)
|
|
216
|
+
self._raise_for_status(response, method, path, params=params)
|
|
215
217
|
self._log_success_response(response, request_logger)
|
|
216
218
|
return response # noqa: TRY300
|
|
217
219
|
except RateLimitError as e:
|
|
@@ -287,13 +289,21 @@ class BaseService:
|
|
|
287
289
|
if header_id:
|
|
288
290
|
response_data["request_id"] = header_id
|
|
289
291
|
|
|
290
|
-
def _raise_for_status(
|
|
292
|
+
def _raise_for_status(
|
|
293
|
+
self,
|
|
294
|
+
response: httpx.Response,
|
|
295
|
+
method: str,
|
|
296
|
+
url: str,
|
|
297
|
+
params: dict[str, Any] | None = None,
|
|
298
|
+
) -> None:
|
|
291
299
|
"""Raise appropriate exception for error responses.
|
|
292
300
|
|
|
293
301
|
Args:
|
|
294
302
|
response: The HTTP response to check.
|
|
295
303
|
method: The HTTP method of the request.
|
|
296
304
|
url: The URL path of the request.
|
|
305
|
+
params: The query parameters of the request, logged to disambiguate
|
|
306
|
+
paginated calls that share the same path.
|
|
297
307
|
|
|
298
308
|
Raises:
|
|
299
309
|
AuthenticationError: For 401 responses.
|
|
@@ -319,7 +329,11 @@ class BaseService:
|
|
|
319
329
|
self._inject_request_id_fallback(response_data, response)
|
|
320
330
|
|
|
321
331
|
error_logger = logger.bind(
|
|
322
|
-
method=method,
|
|
332
|
+
method=method,
|
|
333
|
+
url=url,
|
|
334
|
+
params=params,
|
|
335
|
+
status=status_code,
|
|
336
|
+
request_id=response_data.get("request_id"),
|
|
323
337
|
)
|
|
324
338
|
|
|
325
339
|
if status_code == 429: # noqa: PLR2004
|
|
@@ -653,20 +667,23 @@ class BaseService:
|
|
|
653
667
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
654
668
|
offset: int = 0,
|
|
655
669
|
params: dict[str, Any] | None = None,
|
|
670
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
656
671
|
) -> PaginatedResponse[dict[str, Any]]:
|
|
657
672
|
"""Make a paginated GET request.
|
|
658
673
|
|
|
659
674
|
Args:
|
|
660
675
|
path: API endpoint path.
|
|
661
|
-
limit: Maximum number of items to return (
|
|
676
|
+
limit: Maximum number of items to return (default 10).
|
|
662
677
|
offset: Number of items to skip from the beginning (default 0).
|
|
663
678
|
params: Additional query parameters.
|
|
679
|
+
max_limit: Upper bound the limit is clamped to (default 100). Reference/catalog
|
|
680
|
+
endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
664
681
|
|
|
665
682
|
Returns:
|
|
666
683
|
A PaginatedResponse containing the items and pagination metadata.
|
|
667
684
|
"""
|
|
668
685
|
request_params = {
|
|
669
|
-
"limit": min(max(limit, 0),
|
|
686
|
+
"limit": min(max(limit, 0), max_limit), # Clamp to valid range
|
|
670
687
|
"offset": max(offset, 0),
|
|
671
688
|
**(params or {}),
|
|
672
689
|
}
|
|
@@ -682,20 +699,25 @@ class BaseService:
|
|
|
682
699
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
683
700
|
offset: int = 0,
|
|
684
701
|
params: dict[str, Any] | None = None,
|
|
702
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
685
703
|
) -> PaginatedResponse[T]:
|
|
686
704
|
"""Make a paginated GET request and parse items into the given model class.
|
|
687
705
|
|
|
688
706
|
Args:
|
|
689
707
|
path: API endpoint path.
|
|
690
708
|
model_class: Pydantic model class to validate each item into.
|
|
691
|
-
limit: Maximum number of items to return (
|
|
709
|
+
limit: Maximum number of items to return (default 10).
|
|
692
710
|
offset: Number of items to skip from the beginning (default 0).
|
|
693
711
|
params: Additional query parameters.
|
|
712
|
+
max_limit: Upper bound the limit is clamped to (default 100). Reference/catalog
|
|
713
|
+
endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
694
714
|
|
|
695
715
|
Returns:
|
|
696
716
|
A PaginatedResponse containing validated model instances.
|
|
697
717
|
"""
|
|
698
|
-
response = await self._get_paginated(
|
|
718
|
+
response = await self._get_paginated(
|
|
719
|
+
path, limit=limit, offset=offset, params=params, max_limit=max_limit
|
|
720
|
+
)
|
|
699
721
|
return PaginatedResponse(
|
|
700
722
|
items=[model_class.model_validate(item) for item in response.items],
|
|
701
723
|
limit=response.limit,
|
|
@@ -709,6 +731,7 @@ class BaseService:
|
|
|
709
731
|
*,
|
|
710
732
|
limit: int = MAX_PAGE_LIMIT,
|
|
711
733
|
params: dict[str, Any] | None = None,
|
|
734
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
712
735
|
) -> AsyncIterator[dict[str, Any]]:
|
|
713
736
|
"""Iterate through all pages of a paginated endpoint.
|
|
714
737
|
|
|
@@ -719,6 +742,8 @@ class BaseService:
|
|
|
719
742
|
path: API endpoint path.
|
|
720
743
|
limit: Items per page (default 100 for efficiency).
|
|
721
744
|
params: Additional query parameters.
|
|
745
|
+
max_limit: Upper bound the per-page limit is clamped to (default 100).
|
|
746
|
+
Reference/catalog endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
722
747
|
|
|
723
748
|
Yields:
|
|
724
749
|
Individual items from the paginated response.
|
|
@@ -737,6 +762,7 @@ class BaseService:
|
|
|
737
762
|
limit=limit,
|
|
738
763
|
offset=offset,
|
|
739
764
|
params=params,
|
|
765
|
+
max_limit=max_limit,
|
|
740
766
|
)
|
|
741
767
|
|
|
742
768
|
for item in page.items:
|
|
@@ -753,6 +779,7 @@ class BaseService:
|
|
|
753
779
|
*,
|
|
754
780
|
limit: int = MAX_PAGE_LIMIT,
|
|
755
781
|
params: dict[str, Any] | None = None,
|
|
782
|
+
max_limit: int = MAX_PAGE_LIMIT,
|
|
756
783
|
) -> list[dict[str, Any]]:
|
|
757
784
|
"""Fetch all items from a paginated endpoint.
|
|
758
785
|
|
|
@@ -764,8 +791,15 @@ class BaseService:
|
|
|
764
791
|
path: API endpoint path.
|
|
765
792
|
limit: Items per page (default 100 for efficiency).
|
|
766
793
|
params: Additional query parameters.
|
|
794
|
+
max_limit: Upper bound the per-page limit is clamped to (default 100).
|
|
795
|
+
Reference/catalog endpoints pass a higher bound (MAX_REFERENCE_PAGE_LIMIT).
|
|
767
796
|
|
|
768
797
|
Returns:
|
|
769
798
|
A list of all items from all pages.
|
|
770
799
|
"""
|
|
771
|
-
return [
|
|
800
|
+
return [
|
|
801
|
+
item
|
|
802
|
+
async for item in self._iter_all_pages(
|
|
803
|
+
path, limit=limit, params=params, max_limit=max_limit
|
|
804
|
+
)
|
|
805
|
+
]
|
|
@@ -5,6 +5,7 @@ from typing import TYPE_CHECKING
|
|
|
5
5
|
|
|
6
6
|
from vclient.constants import (
|
|
7
7
|
DEFAULT_PAGE_LIMIT,
|
|
8
|
+
MAX_REFERENCE_PAGE_LIMIT,
|
|
8
9
|
BlueprintTraitOrderBy,
|
|
9
10
|
CharacterClass,
|
|
10
11
|
GameVersion,
|
|
@@ -65,6 +66,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
65
66
|
SheetSection,
|
|
66
67
|
limit=limit,
|
|
67
68
|
offset=offset,
|
|
69
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
68
70
|
params=self._build_params(game_version=game_version, character_class=character_class),
|
|
69
71
|
)
|
|
70
72
|
|
|
@@ -91,6 +93,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
91
93
|
"""Iterate through all character blueprint sections."""
|
|
92
94
|
async for section in self._iter_all_pages(
|
|
93
95
|
self._format_endpoint(Endpoints.BLUEPRINT_SECTIONS),
|
|
96
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
97
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
94
98
|
params=self._build_params(game_version=game_version, character_class=character_class),
|
|
95
99
|
):
|
|
96
100
|
yield SheetSection.model_validate(section)
|
|
@@ -122,6 +126,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
122
126
|
TraitCategory,
|
|
123
127
|
limit=limit,
|
|
124
128
|
offset=offset,
|
|
129
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
125
130
|
params=self._build_params(
|
|
126
131
|
game_version=game_version,
|
|
127
132
|
section_id=section_id,
|
|
@@ -156,6 +161,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
156
161
|
"""Iterate through all character blueprint categories."""
|
|
157
162
|
async for category in self._iter_all_pages(
|
|
158
163
|
self._format_endpoint(Endpoints.BLUEPRINT_CATEGORIES),
|
|
164
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
165
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
159
166
|
params=self._build_params(
|
|
160
167
|
game_version=game_version,
|
|
161
168
|
section_id=section_id,
|
|
@@ -191,6 +198,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
191
198
|
TraitSubcategory,
|
|
192
199
|
limit=limit,
|
|
193
200
|
offset=offset,
|
|
201
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
194
202
|
params=self._build_params(
|
|
195
203
|
game_version=game_version,
|
|
196
204
|
category_id=category_id,
|
|
@@ -225,6 +233,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
225
233
|
"""Iterate through all character blueprint subcategories."""
|
|
226
234
|
async for subcategory in self._iter_all_pages(
|
|
227
235
|
self._format_endpoint(Endpoints.BLUEPRINT_SUBCATEGORIES),
|
|
236
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
237
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
228
238
|
params=self._build_params(
|
|
229
239
|
game_version=game_version,
|
|
230
240
|
category_id=category_id,
|
|
@@ -264,6 +274,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
264
274
|
Trait,
|
|
265
275
|
limit=limit,
|
|
266
276
|
offset=offset,
|
|
277
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
267
278
|
params=self._build_params(
|
|
268
279
|
character_class=character_class,
|
|
269
280
|
category_id=category_id,
|
|
@@ -314,6 +325,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
314
325
|
"""Iterate through all character blueprint traits."""
|
|
315
326
|
async for trait in self._iter_all_pages(
|
|
316
327
|
self._format_endpoint(Endpoints.BLUEPRINT_TRAITS),
|
|
328
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
329
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
317
330
|
params=self._build_params(
|
|
318
331
|
character_class=character_class,
|
|
319
332
|
category_id=category_id,
|
|
@@ -347,6 +360,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
347
360
|
CharacterConcept,
|
|
348
361
|
limit=limit,
|
|
349
362
|
offset=offset,
|
|
363
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
350
364
|
)
|
|
351
365
|
|
|
352
366
|
async def list_all_concepts(self) -> list[CharacterConcept]:
|
|
@@ -357,6 +371,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
357
371
|
"""Iterate through all character concepts."""
|
|
358
372
|
async for concept in self._iter_all_pages(
|
|
359
373
|
self._format_endpoint(Endpoints.CONCEPTS),
|
|
374
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
375
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
360
376
|
):
|
|
361
377
|
yield CharacterConcept.model_validate(concept)
|
|
362
378
|
|
|
@@ -383,6 +399,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
383
399
|
VampireClan,
|
|
384
400
|
limit=limit,
|
|
385
401
|
offset=offset,
|
|
402
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
386
403
|
params=self._build_params(game_version=game_version),
|
|
387
404
|
)
|
|
388
405
|
|
|
@@ -398,6 +415,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
398
415
|
"""Iterate through all vampire clans."""
|
|
399
416
|
async for clan in self._iter_all_pages(
|
|
400
417
|
self._format_endpoint(Endpoints.VAMPIRE_CLANS),
|
|
418
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
419
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
401
420
|
params=self._build_params(game_version=game_version),
|
|
402
421
|
):
|
|
403
422
|
yield VampireClan.model_validate(clan)
|
|
@@ -425,6 +444,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
425
444
|
WerewolfAuspice,
|
|
426
445
|
limit=limit,
|
|
427
446
|
offset=offset,
|
|
447
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
428
448
|
params=self._build_params(game_version=game_version),
|
|
429
449
|
)
|
|
430
450
|
|
|
@@ -442,6 +462,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
442
462
|
"""Iterate through all werewolf auspices."""
|
|
443
463
|
async for auspice in self._iter_all_pages(
|
|
444
464
|
self._format_endpoint(Endpoints.WEREWOLF_AUSPICES),
|
|
465
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
466
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
445
467
|
params=self._build_params(game_version=game_version),
|
|
446
468
|
):
|
|
447
469
|
yield WerewolfAuspice.model_validate(auspice)
|
|
@@ -471,6 +493,7 @@ class CharacterBlueprintService(BaseService):
|
|
|
471
493
|
WerewolfTribe,
|
|
472
494
|
limit=limit,
|
|
473
495
|
offset=offset,
|
|
496
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
474
497
|
params=self._build_params(game_version=game_version),
|
|
475
498
|
)
|
|
476
499
|
|
|
@@ -486,6 +509,8 @@ class CharacterBlueprintService(BaseService):
|
|
|
486
509
|
"""Iterate through all werewolf tribes."""
|
|
487
510
|
async for tribe in self._iter_all_pages(
|
|
488
511
|
self._format_endpoint(Endpoints.WEREWOLF_TRIBES),
|
|
512
|
+
limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
513
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
489
514
|
params=self._build_params(game_version=game_version),
|
|
490
515
|
):
|
|
491
516
|
yield WerewolfTribe.model_validate(tribe)
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/dictionary.py
RENAMED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from collections.abc import AsyncIterator
|
|
4
4
|
from typing import TYPE_CHECKING
|
|
5
5
|
|
|
6
|
-
from vclient.constants import DEFAULT_PAGE_LIMIT
|
|
6
|
+
from vclient.constants import DEFAULT_PAGE_LIMIT, MAX_REFERENCE_PAGE_LIMIT
|
|
7
7
|
from vclient.endpoints import Endpoints
|
|
8
8
|
from vclient.models import (
|
|
9
9
|
DictionaryTerm,
|
|
@@ -53,6 +53,7 @@ class DictionaryService(BaseService):
|
|
|
53
53
|
DictionaryTerm,
|
|
54
54
|
limit=limit,
|
|
55
55
|
offset=offset,
|
|
56
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
56
57
|
params=self._build_params(term=term),
|
|
57
58
|
)
|
|
58
59
|
|
|
@@ -61,12 +62,13 @@ class DictionaryService(BaseService):
|
|
|
61
62
|
return [term async for term in self.iter_all(term=term)]
|
|
62
63
|
|
|
63
64
|
async def iter_all(
|
|
64
|
-
self, *, term: str | None = None, limit: int =
|
|
65
|
+
self, *, term: str | None = None, limit: int = MAX_REFERENCE_PAGE_LIMIT
|
|
65
66
|
) -> AsyncIterator[DictionaryTerm]:
|
|
66
67
|
"""Iterate through all dictionary terms."""
|
|
67
68
|
async for item in self._iter_all_pages(
|
|
68
69
|
self._format_endpoint(Endpoints.DICTIONARY_TERMS),
|
|
69
70
|
limit=limit,
|
|
71
|
+
max_limit=MAX_REFERENCE_PAGE_LIMIT,
|
|
70
72
|
params=self._build_params(term=term),
|
|
71
73
|
):
|
|
72
74
|
yield DictionaryTerm.model_validate(item)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/registry.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/services/users.py
RENAMED
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/_sync/testing/_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/__init__.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/audit_logs.py
RENAMED
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/campaigns.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/chapters.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/characters.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/companies.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/developers.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/diceroll.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/dictionary.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/full_sheet.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/global_admin.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/pagination.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/shared.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/system.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/models/user_lookup.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/campaigns.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/characters.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/companies.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/developers.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/dicerolls.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/global_admin.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/options.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/system.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/user_lookup.py
RENAMED
|
File without changes
|
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/services/users.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/__init__.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_client.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_factories.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_router.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/testing/_routes.py
RENAMED
|
File without changes
|
{valentina_python_client-2.4.1 → valentina_python_client-2.5.0}/src/vclient/validate_constants.py
RENAMED
|
File without changes
|