valentina-python-client 3.4.0__tar.gz → 3.5.1__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-3.4.0 → valentina_python_client-3.5.1}/PKG-INFO +1 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/pyproject.toml +1 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/pyproject.toml.orig +1 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/__init__.py +1 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/client.py +9 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/base.py +8 -7
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/campaign_book_chapters.py +7 -3
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/campaign_books.py +5 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/campaigns.py +5 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/character_traits.py +12 -23
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/characters.py +12 -24
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/developers.py +7 -3
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/identity.py +7 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/options.py +3 -3
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/users.py +19 -14
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/client.py +9 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/constants.py +0 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/__init__.py +0 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/character_trait.py +28 -56
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/characters.py +1 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/users.py +1 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/base.py +8 -11
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/campaign_book_chapters.py +7 -3
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/campaign_books.py +5 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/campaigns.py +5 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/character_traits.py +11 -18
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/characters.py +11 -19
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/developers.py +7 -3
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/identity.py +7 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/options.py +3 -3
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/users.py +19 -14
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/testing/__init__.py +0 -2
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/testing/_factories.py +18 -38
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/testing/_router.py +0 -3
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/testing/_routes.py +5 -5
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/validate_constants.py +0 -1
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/LICENSE +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/README.md +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_codegen.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/__init__.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/registry.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/__init__.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/_audit_params.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/character_autogen.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/character_blueprint.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/companies.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/dicerolls.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/dictionary.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/global_admin.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/system.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/user_lookup.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/testing/__init__.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/testing/_client.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/config.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/endpoints.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/exceptions.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/audit_logs.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/books.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/campaigns.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/chapters.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/character_autogen.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/character_blueprint.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/companies.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/developers.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/diceroll.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/dictionary.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/full_sheet.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/global_admin.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/pagination.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/shared.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/system.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/user_lookup.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/py.typed +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/registry.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/__init__.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/_audit_params.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/character_autogen.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/character_blueprint.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/companies.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/dicerolls.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/dictionary.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/global_admin.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/system.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/services/user_lookup.py +0 -0
- {valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/testing/_client.py +0 -0
|
@@ -200,6 +200,15 @@ class SyncVClient:
|
|
|
200
200
|
"""Check if the client has been closed."""
|
|
201
201
|
return self._http.is_closed
|
|
202
202
|
|
|
203
|
+
def _set_api_key(self, api_key: str) -> None:
|
|
204
|
+
"""Send a new API key on every later request from this client and its services.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
api_key: The API key to authenticate with from now on.
|
|
208
|
+
"""
|
|
209
|
+
self._config.api_key = api_key
|
|
210
|
+
self._http.headers[API_KEY_HEADER] = api_key
|
|
211
|
+
|
|
203
212
|
@property
|
|
204
213
|
def default_company_id(self) -> str | None:
|
|
205
214
|
"""Return the default company ID from config."""
|
{valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/base.py
RENAMED
|
@@ -91,21 +91,22 @@ class SyncBaseService:
|
|
|
91
91
|
def _calculate_backoff_delay(self, attempt: int, retry_after: int | None) -> float:
|
|
92
92
|
"""Calculate the delay before the next retry attempt.
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
Wait the server's ``retry_after`` when it gives one, since the server knows
|
|
95
|
+
when capacity returns. Otherwise use exponential backoff:
|
|
96
|
+
``retry_delay * 2 ** attempt``. Either way, add up to 25% random jitter so
|
|
97
|
+
clients that were limited together do not retry together.
|
|
96
98
|
|
|
97
99
|
Args:
|
|
98
100
|
attempt: The current attempt number (0-indexed).
|
|
99
|
-
retry_after: Seconds to wait from the RateLimit header, or None.
|
|
101
|
+
retry_after: Seconds to wait from the RateLimit or Retry-After header, or None.
|
|
100
102
|
|
|
101
103
|
Returns:
|
|
102
104
|
Number of seconds to wait before retrying.
|
|
103
105
|
"""
|
|
104
|
-
config = self._client._config
|
|
105
|
-
base_delay = config.retry_delay
|
|
106
106
|
if retry_after is not None and retry_after > 0:
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
delay = float(retry_after)
|
|
108
|
+
else:
|
|
109
|
+
delay = self._client._config.retry_delay * 2**attempt
|
|
109
110
|
jitter = random.uniform(0, delay * 0.25)
|
|
110
111
|
return delay + jitter
|
|
111
112
|
|
|
@@ -26,7 +26,11 @@ if TYPE_CHECKING:
|
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
class SyncChaptersService(SyncBaseService):
|
|
29
|
-
"""Service for managing campaign book chapters within a campaign book in the Valentina API.
|
|
29
|
+
"""Service for managing campaign book chapters within a campaign book in the Valentina API.
|
|
30
|
+
|
|
31
|
+
Requests return 403 (``AuthorizationError``) when the ``on_behalf_of`` user is
|
|
32
|
+
UNAPPROVED or DEACTIVATED.
|
|
33
|
+
"""
|
|
30
34
|
|
|
31
35
|
def __init__(
|
|
32
36
|
self,
|
|
@@ -413,7 +417,7 @@ class SyncChaptersService(SyncBaseService):
|
|
|
413
417
|
Only image files are accepted: PNG, JPEG, GIF, and WEBP. Any other
|
|
414
418
|
upload (documents, audio, video, archives, SVG, or a non-image payload
|
|
415
419
|
mislabeled as an image) is rejected with 400 Bad Request, as are
|
|
416
|
-
|
|
420
|
+
images over 24 megapixels (width x height). The stored
|
|
417
421
|
``mime_type`` is detected from the file's bytes; the ``content_type``
|
|
418
422
|
argument is ignored server-side and cannot change or bypass the stored
|
|
419
423
|
type. Uploaded assets therefore always have ``asset_type == "image"``.
|
|
@@ -450,7 +454,7 @@ class SyncChaptersService(SyncBaseService):
|
|
|
450
454
|
asset_id: The ID of the asset to delete.
|
|
451
455
|
|
|
452
456
|
Raises:
|
|
453
|
-
NotFoundError: If the asset does not exist.
|
|
457
|
+
NotFoundError: If the asset does not exist or belongs to a different chapter.
|
|
454
458
|
AuthorizationError: If you don't have appropriate access.
|
|
455
459
|
"""
|
|
456
460
|
self._delete(
|
|
@@ -34,6 +34,9 @@ class SyncBooksService(SyncBaseService):
|
|
|
34
34
|
Provides methods to create, retrieve, update, and delete campaign books,
|
|
35
35
|
as well as access book notes and assets.
|
|
36
36
|
|
|
37
|
+
Requests return 403 (``AuthorizationError``) when the ``on_behalf_of`` user is
|
|
38
|
+
UNAPPROVED or DEACTIVATED.
|
|
39
|
+
|
|
37
40
|
Example:
|
|
38
41
|
>>> async with SyncVClient() as client:
|
|
39
42
|
... books = client.books("company_id", "campaign_id")
|
|
@@ -477,7 +480,7 @@ class SyncBooksService(SyncBaseService):
|
|
|
477
480
|
Only image files are accepted: PNG, JPEG, GIF, and WEBP. Any other
|
|
478
481
|
upload (documents, audio, video, archives, SVG, or a non-image payload
|
|
479
482
|
mislabeled as an image) is rejected with 400 Bad Request, as are
|
|
480
|
-
|
|
483
|
+
images over 24 megapixels (width x height). The stored
|
|
481
484
|
``mime_type`` is detected from the file's bytes; the ``content_type``
|
|
482
485
|
argument is ignored server-side and cannot change or bypass the stored
|
|
483
486
|
type. Uploaded assets therefore always have ``asset_type == "image"``.
|
|
@@ -514,7 +517,7 @@ class SyncBooksService(SyncBaseService):
|
|
|
514
517
|
asset_id: The ID of the asset to delete.
|
|
515
518
|
|
|
516
519
|
Raises:
|
|
517
|
-
NotFoundError: If the asset does not exist.
|
|
520
|
+
NotFoundError: If the asset does not exist or belongs to a different book.
|
|
518
521
|
AuthorizationError: If you don't have appropriate access.
|
|
519
522
|
"""
|
|
520
523
|
self._delete(
|
|
@@ -33,6 +33,9 @@ class SyncCampaignsService(SyncBaseService):
|
|
|
33
33
|
Provides methods to create, retrieve, update, and delete campaigns,
|
|
34
34
|
as well as access campaign statistics, assets, and notes.
|
|
35
35
|
|
|
36
|
+
Requests return 403 (``AuthorizationError``) when the ``on_behalf_of`` user is
|
|
37
|
+
UNAPPROVED or DEACTIVATED.
|
|
38
|
+
|
|
36
39
|
Example:
|
|
37
40
|
>>> async with SyncVClient() as client:
|
|
38
41
|
... campaigns = client.campaigns("company_id")
|
|
@@ -308,7 +311,7 @@ class SyncCampaignsService(SyncBaseService):
|
|
|
308
311
|
asset_id: The ID of the asset to delete.
|
|
309
312
|
|
|
310
313
|
Raises:
|
|
311
|
-
NotFoundError: If the asset does not exist.
|
|
314
|
+
NotFoundError: If the asset does not exist or belongs to a different campaign.
|
|
312
315
|
AuthorizationError: If you don't have appropriate access.
|
|
313
316
|
"""
|
|
314
317
|
self._delete(
|
|
@@ -327,7 +330,7 @@ class SyncCampaignsService(SyncBaseService):
|
|
|
327
330
|
Only image files are accepted: PNG, JPEG, GIF, and WEBP. Any other
|
|
328
331
|
upload (documents, audio, video, archives, SVG, or a non-image payload
|
|
329
332
|
mislabeled as an image) is rejected with 400 Bad Request, as are
|
|
330
|
-
|
|
333
|
+
images over 24 megapixels (width x height). The stored
|
|
331
334
|
``mime_type`` is detected from the file's bytes; the ``content_type``
|
|
332
335
|
argument is ignored server-side and cannot change or bypass the stored
|
|
333
336
|
type. Uploaded assets therefore always have ``asset_type == "image"``.
|
|
@@ -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, TrackerAction, TraitModifyCurrency
|
|
9
9
|
from vclient.endpoints import Endpoints
|
|
10
10
|
from vclient.models import (
|
|
11
11
|
_TRACKER_ADAPTER,
|
|
@@ -407,7 +407,7 @@ class SyncCharacterTraitsService(SyncBaseService):
|
|
|
407
407
|
character_trait_id: The ID of the character trait.
|
|
408
408
|
|
|
409
409
|
Returns:
|
|
410
|
-
A CounterTracker
|
|
410
|
+
A CounterTracker or StainsTracker. Switch on ``type``.
|
|
411
411
|
|
|
412
412
|
Raises:
|
|
413
413
|
NotFoundError: If the trait has no tracker for the character's game version.
|
|
@@ -425,16 +425,15 @@ class SyncCharacterTraitsService(SyncBaseService):
|
|
|
425
425
|
) -> Tracker:
|
|
426
426
|
"""Replace the full state of a trait tracker, such as to correct a mistake.
|
|
427
427
|
|
|
428
|
-
Send only the
|
|
429
|
-
``
|
|
430
|
-
fields reset to 0, so an empty request clears a damage or stains tracker. Use
|
|
428
|
+
Send only the field for the tracker's type: ``current`` for counters (required) or
|
|
429
|
+
``stains`` for stains. An empty request clears a stains tracker. Use
|
|
431
430
|
``apply_tracker_action`` for in-play changes instead.
|
|
432
431
|
|
|
433
432
|
Args:
|
|
434
433
|
character_trait_id: The ID of the character trait.
|
|
435
434
|
request: A TrackerStateSet model, OR pass fields as keyword arguments.
|
|
436
435
|
**kwargs: Fields for TrackerStateSet if request is not provided.
|
|
437
|
-
Accepts: current,
|
|
436
|
+
Accepts: current, stains (int >= 0).
|
|
438
437
|
|
|
439
438
|
Returns:
|
|
440
439
|
The updated tracker.
|
|
@@ -442,7 +441,7 @@ class SyncCharacterTraitsService(SyncBaseService):
|
|
|
442
441
|
Raises:
|
|
443
442
|
NotFoundError: If the trait has no tracker for the character's game version.
|
|
444
443
|
AuthorizationError: If you are not the character's player or a storyteller.
|
|
445
|
-
RequestValidationError: If a value is negative.
|
|
444
|
+
RequestValidationError: If a value is negative or a field is unknown.
|
|
446
445
|
ValidationError: If a field does not fit the tracker type, a counter has no
|
|
447
446
|
``current``, or a value exceeds the tracker size.
|
|
448
447
|
"""
|
|
@@ -456,25 +455,17 @@ class SyncCharacterTraitsService(SyncBaseService):
|
|
|
456
455
|
return _TRACKER_ADAPTER.validate_python(response.json())
|
|
457
456
|
|
|
458
457
|
def apply_tracker_action(
|
|
459
|
-
self,
|
|
460
|
-
character_trait_id: str,
|
|
461
|
-
action: TrackerAction,
|
|
462
|
-
*,
|
|
463
|
-
amount: int = 1,
|
|
464
|
-
damage_type: DamageType | None = None,
|
|
458
|
+
self, character_trait_id: str, action: TrackerAction, *, amount: int = 1
|
|
465
459
|
) -> Tracker:
|
|
466
460
|
"""Apply one in-play action to a trait tracker, such as spending Willpower.
|
|
467
461
|
|
|
468
|
-
The
|
|
469
|
-
|
|
470
|
-
``options.get_options()``. A STAINS response reports overflow into Willpower in
|
|
471
|
-
``willpower_damage_applied``.
|
|
462
|
+
The actions each tracker accepts are listed in
|
|
463
|
+
``characters.TrackerRules[game_version][tracker.type]`` from ``options.get_options()``.
|
|
472
464
|
|
|
473
465
|
Args:
|
|
474
466
|
character_trait_id: The ID of the character trait.
|
|
475
467
|
action: The action to apply.
|
|
476
468
|
amount: How many points to apply. Must be at least 1.
|
|
477
|
-
damage_type: The damage type for ``damage`` and ``heal`` on damage tracks.
|
|
478
469
|
|
|
479
470
|
Returns:
|
|
480
471
|
The updated tracker.
|
|
@@ -483,12 +474,10 @@ class SyncCharacterTraitsService(SyncBaseService):
|
|
|
483
474
|
NotFoundError: If the trait has no tracker for the character's game version.
|
|
484
475
|
AuthorizationError: If you are not the character's player or a storyteller.
|
|
485
476
|
RequestValidationError: If ``amount`` is less than 1.
|
|
486
|
-
ValidationError: If the action
|
|
487
|
-
|
|
477
|
+
ValidationError: If the action does not fit the tracker or a spend exceeds the
|
|
478
|
+
current value.
|
|
488
479
|
"""
|
|
489
|
-
body = self._validate_request(
|
|
490
|
-
_TrackerAction, action=action, amount=amount, damage_type=damage_type
|
|
491
|
-
)
|
|
480
|
+
body = self._validate_request(_TrackerAction, action=action, amount=amount)
|
|
492
481
|
response = self._post(
|
|
493
482
|
self._format_endpoint(
|
|
494
483
|
Endpoints.CHARACTER_TRAIT_TRACKER_ACTIONS, character_trait_id=character_trait_id
|
|
@@ -12,7 +12,6 @@ from vclient.constants import (
|
|
|
12
12
|
CharacterInclude,
|
|
13
13
|
CharacterStatus,
|
|
14
14
|
CharacterType,
|
|
15
|
-
DamageType,
|
|
16
15
|
TrackerAction,
|
|
17
16
|
)
|
|
18
17
|
from vclient.endpoints import Endpoints
|
|
@@ -496,7 +495,7 @@ class SyncCharactersService(SyncBaseService):
|
|
|
496
495
|
asset_id: The ID of the asset to delete.
|
|
497
496
|
|
|
498
497
|
Raises:
|
|
499
|
-
NotFoundError: If the asset does not exist.
|
|
498
|
+
NotFoundError: If the asset does not exist or belongs to a different character.
|
|
500
499
|
AuthorizationError: If you don't have appropriate access.
|
|
501
500
|
"""
|
|
502
501
|
self._delete(
|
|
@@ -515,7 +514,7 @@ class SyncCharactersService(SyncBaseService):
|
|
|
515
514
|
Only image files are accepted: PNG, JPEG, GIF, and WEBP. Any other
|
|
516
515
|
upload (documents, audio, video, archives, SVG, or a non-image payload
|
|
517
516
|
mislabeled as an image) is rejected with 400 Bad Request, as are
|
|
518
|
-
|
|
517
|
+
images over 24 megapixels (width x height). The stored
|
|
519
518
|
``mime_type`` is detected from the file's bytes; the ``content_type``
|
|
520
519
|
argument is ignored server-side and cannot change or bypass the stored
|
|
521
520
|
type. Uploaded assets therefore always have ``asset_type == "image"``.
|
|
@@ -905,15 +904,14 @@ class SyncCharactersService(SyncBaseService):
|
|
|
905
904
|
) -> Health:
|
|
906
905
|
"""Replace a character's full health state, such as to correct a mistake.
|
|
907
906
|
|
|
908
|
-
Every field is sent, so omitted fields reset to 0.
|
|
909
|
-
|
|
910
|
-
``extra_levels`` applies to both. Use ``apply_health_action`` for in-play changes.
|
|
907
|
+
Every field is sent, so omitted fields reset to 0. Use ``apply_health_action`` for
|
|
908
|
+
in-play changes.
|
|
911
909
|
|
|
912
910
|
Args:
|
|
913
911
|
character_id: The ID of the character.
|
|
914
912
|
request: A HealthStateSet model, OR pass fields as keyword arguments.
|
|
915
913
|
**kwargs: Fields for HealthStateSet if request is not provided.
|
|
916
|
-
Accepts: extra_levels,
|
|
914
|
+
Accepts: extra_levels, damage (int >= 0).
|
|
917
915
|
|
|
918
916
|
Returns:
|
|
919
917
|
The updated Health.
|
|
@@ -921,9 +919,8 @@ class SyncCharactersService(SyncBaseService):
|
|
|
921
919
|
Raises:
|
|
922
920
|
NotFoundError: If the character does not exist or has no health track.
|
|
923
921
|
AuthorizationError: If you are not the character's player or a storyteller.
|
|
924
|
-
RequestValidationError: If a value is negative.
|
|
925
|
-
ValidationError: If
|
|
926
|
-
marks exceed the track size.
|
|
922
|
+
RequestValidationError: If a value is negative or a field is unknown.
|
|
923
|
+
ValidationError: If the damage exceeds the track size.
|
|
927
924
|
"""
|
|
928
925
|
body = request if request is not None else self._validate_request(HealthStateSet, **kwargs)
|
|
929
926
|
response = self._put(
|
|
@@ -933,24 +930,17 @@ class SyncCharactersService(SyncBaseService):
|
|
|
933
930
|
return Health.model_validate(response.json())
|
|
934
931
|
|
|
935
932
|
def apply_health_action(
|
|
936
|
-
self,
|
|
937
|
-
character_id: str,
|
|
938
|
-
action: TrackerAction,
|
|
939
|
-
*,
|
|
940
|
-
amount: int = 1,
|
|
941
|
-
damage_type: DamageType | None = None,
|
|
933
|
+
self, character_id: str, action: TrackerAction, *, amount: int = 1
|
|
942
934
|
) -> Health:
|
|
943
935
|
"""Apply one in-play action to a character's health, such as taking damage.
|
|
944
936
|
|
|
945
|
-
Health accepts ``damage``, ``heal``, and ``reset``.
|
|
946
|
-
|
|
947
|
-
and ``AGGRAVATED``. The server applies overflow and upgrade rules.
|
|
937
|
+
Health accepts ``damage``, ``heal``, and ``reset``. Damage past a full track and
|
|
938
|
+
healing past 0 are dropped.
|
|
948
939
|
|
|
949
940
|
Args:
|
|
950
941
|
character_id: The ID of the character.
|
|
951
942
|
action: The action to apply.
|
|
952
943
|
amount: How many points to apply. Must be at least 1.
|
|
953
|
-
damage_type: The damage type for ``damage`` and ``heal``.
|
|
954
944
|
|
|
955
945
|
Returns:
|
|
956
946
|
The updated Health.
|
|
@@ -959,11 +949,9 @@ class SyncCharactersService(SyncBaseService):
|
|
|
959
949
|
NotFoundError: If the character does not exist or has no health track.
|
|
960
950
|
AuthorizationError: If you are not the character's player or a storyteller.
|
|
961
951
|
RequestValidationError: If ``amount`` is less than 1.
|
|
962
|
-
ValidationError: If the action
|
|
952
|
+
ValidationError: If the action does not apply to health.
|
|
963
953
|
"""
|
|
964
|
-
body = self._validate_request(
|
|
965
|
-
_TrackerAction, action=action, amount=amount, damage_type=damage_type
|
|
966
|
-
)
|
|
954
|
+
body = self._validate_request(_TrackerAction, action=action, amount=amount)
|
|
967
955
|
response = self._post(
|
|
968
956
|
self._format_endpoint(Endpoints.CHARACTER_HEALTH_ACTIONS, character_id=character_id),
|
|
969
957
|
json=body.model_dump(exclude_none=True, mode="json"),
|
|
@@ -64,8 +64,10 @@ class SyncDeveloperService(SyncBaseService):
|
|
|
64
64
|
def regenerate_api_key(self) -> MeDeveloperWithApiKey:
|
|
65
65
|
"""Generate a new API key for the current developer.
|
|
66
66
|
|
|
67
|
-
The current key
|
|
68
|
-
|
|
67
|
+
The API invalidates the current key at once, so this client switches to
|
|
68
|
+
the new key for every later request, including those from services it
|
|
69
|
+
already created. Other clients that still hold the old key get
|
|
70
|
+
``AuthenticationError`` until they are given the new one.
|
|
69
71
|
|
|
70
72
|
**Be certain to save the API key from the response. It will not be displayed again.**
|
|
71
73
|
|
|
@@ -76,4 +78,6 @@ class SyncDeveloperService(SyncBaseService):
|
|
|
76
78
|
AuthenticationError: If the current API key is invalid.
|
|
77
79
|
"""
|
|
78
80
|
response = self._post(Endpoints.DEVELOPER_ME_NEW_KEY)
|
|
79
|
-
|
|
81
|
+
developer = MeDeveloperWithApiKey.model_validate(response.json())
|
|
82
|
+
self._client._set_api_key(developer.api_key)
|
|
83
|
+
return developer
|
|
@@ -18,7 +18,10 @@ class SyncIdentityService(SyncBaseService):
|
|
|
18
18
|
ID token for apple/google, an OAuth access token for discord/github). The
|
|
19
19
|
API verifies the credential with the provider and resolves the user in
|
|
20
20
|
order: match by provider ID, auto-link by provider-verified email, or
|
|
21
|
-
create a new UNAPPROVED user.
|
|
21
|
+
create a new UNAPPROVED user. Auto-link never replaces an identity: when
|
|
22
|
+
the email's user already holds a different identity from the same
|
|
23
|
+
provider, a new user is created instead. OIDC ID tokens must carry
|
|
24
|
+
``exp`` and ``iat`` claims.
|
|
22
25
|
|
|
23
26
|
This service does not require an acting user (no On-Behalf-Of header).
|
|
24
27
|
Authentication is via developer API key only.
|
|
@@ -50,7 +53,9 @@ class SyncIdentityService(SyncBaseService):
|
|
|
50
53
|
The returned ``resolution`` field reports which path the API took:
|
|
51
54
|
``matched`` (an existing user holds this provider identity), ``linked``
|
|
52
55
|
(the identity was auto-linked onto an existing user by provider-verified
|
|
53
|
-
email), or ``created`` (a new UNAPPROVED user was registered).
|
|
56
|
+
email), or ``created`` (a new UNAPPROVED user was registered). An email
|
|
57
|
+
match whose user already holds a different identity from the same
|
|
58
|
+
provider resolves to ``created``, not ``linked``.
|
|
54
59
|
|
|
55
60
|
Args:
|
|
56
61
|
request: A UserIdentifyDTO model, OR pass fields as keyword arguments.
|
|
@@ -36,9 +36,9 @@ class SyncOptionsService(SyncBaseService):
|
|
|
36
36
|
"""Retrieve all options and enumerations for the api.
|
|
37
37
|
|
|
38
38
|
Most values are lists of enum values. ``characters.TrackerRules`` is a nested map
|
|
39
|
-
``{game_version: {
|
|
40
|
-
``
|
|
41
|
-
|
|
39
|
+
``{game_version: {tracker_type: {"actions": [...]}}}``. Health is keyed by its
|
|
40
|
+
``type``, ``DAMAGE``. Use it to choose which tracker actions to offer instead of
|
|
41
|
+
hardcoding them.
|
|
42
42
|
|
|
43
43
|
Returns:
|
|
44
44
|
A dictionary of options and enumerations for the api.
|
{valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/_sync/services/users.py
RENAMED
|
@@ -547,8 +547,9 @@ class SyncUsersService(SyncBaseService):
|
|
|
547
547
|
asset_id: The ID of the asset to delete.
|
|
548
548
|
|
|
549
549
|
Raises:
|
|
550
|
-
NotFoundError: If the asset does not exist.
|
|
551
|
-
AuthorizationError: If
|
|
550
|
+
NotFoundError: If the asset does not exist or belongs to a different user.
|
|
551
|
+
AuthorizationError: If the acting user is neither ``user_id`` nor a
|
|
552
|
+
company admin.
|
|
552
553
|
"""
|
|
553
554
|
self._delete(
|
|
554
555
|
self._format_endpoint(Endpoints.USER_ASSET, user_id=user_id, asset_id=asset_id)
|
|
@@ -564,7 +565,7 @@ class SyncUsersService(SyncBaseService):
|
|
|
564
565
|
Only image files are accepted: PNG, JPEG, GIF, and WEBP. Any other
|
|
565
566
|
upload (documents, audio, video, archives, SVG, or a non-image payload
|
|
566
567
|
mislabeled as an image) is rejected with 400 Bad Request, as are
|
|
567
|
-
|
|
568
|
+
images over 24 megapixels (width x height). The stored
|
|
568
569
|
``mime_type`` is detected from the file's bytes; the ``content_type``
|
|
569
570
|
argument is ignored server-side and cannot change or bypass the stored
|
|
570
571
|
type. Uploaded assets therefore always have ``asset_type == "image"``.
|
|
@@ -580,7 +581,8 @@ class SyncUsersService(SyncBaseService):
|
|
|
580
581
|
|
|
581
582
|
Raises:
|
|
582
583
|
NotFoundError: If the user does not exist.
|
|
583
|
-
AuthorizationError: If
|
|
584
|
+
AuthorizationError: If the acting user is neither ``user_id`` nor a
|
|
585
|
+
company admin.
|
|
584
586
|
ValidationError: If the file is invalid or exceeds size limits.
|
|
585
587
|
"""
|
|
586
588
|
if content_type is None:
|
|
@@ -596,10 +598,10 @@ class SyncUsersService(SyncBaseService):
|
|
|
596
598
|
) -> User:
|
|
597
599
|
"""Upload a custom avatar for a user, replacing any existing one.
|
|
598
600
|
|
|
599
|
-
Accepts PNG, JPEG, WEBP, or GIF (first frame) up to 5 MB
|
|
600
|
-
normalizes the image to a 512x512 WebP and it
|
|
601
|
-
identity-provider-derived avatar. Requires the
|
|
602
|
-
(permitted for the user themselves or an admin).
|
|
601
|
+
Accepts PNG, JPEG, WEBP, or GIF (first frame) up to 5 MB and 24
|
|
602
|
+
megapixels. The server normalizes the image to a 512x512 WebP and it
|
|
603
|
+
overrides any identity-provider-derived avatar. Requires the
|
|
604
|
+
``On-Behalf-Of`` header (permitted for the user themselves or an admin).
|
|
603
605
|
|
|
604
606
|
Args:
|
|
605
607
|
user_id: The ID of the user to set the avatar for.
|
|
@@ -667,7 +669,7 @@ class SyncUsersService(SyncBaseService):
|
|
|
667
669
|
Args:
|
|
668
670
|
user_id: The ID of the user to award XP to.
|
|
669
671
|
campaign_id: The ID of the campaign to add XP for.
|
|
670
|
-
amount: The amount of XP to add.
|
|
672
|
+
amount: The amount of XP to add. Must be at least 1.
|
|
671
673
|
|
|
672
674
|
Returns:
|
|
673
675
|
Updated CampaignExperience object.
|
|
@@ -692,7 +694,7 @@ class SyncUsersService(SyncBaseService):
|
|
|
692
694
|
Args:
|
|
693
695
|
user_id: The ID of the user to remove XP from.
|
|
694
696
|
campaign_id: The ID of the campaign to remove XP for.
|
|
695
|
-
amount: The amount of XP to remove.
|
|
697
|
+
amount: The amount of XP to remove. Must be at least 1.
|
|
696
698
|
|
|
697
699
|
Returns:
|
|
698
700
|
Updated CampaignExperience object.
|
|
@@ -719,7 +721,7 @@ class SyncUsersService(SyncBaseService):
|
|
|
719
721
|
Args:
|
|
720
722
|
user_id: The ID of the user to award cool points to.
|
|
721
723
|
campaign_id: The ID of the campaign to add cool points for.
|
|
722
|
-
amount: The amount of cool points to add.
|
|
724
|
+
amount: The amount of cool points to add. Must be at least 1.
|
|
723
725
|
|
|
724
726
|
Returns:
|
|
725
727
|
Updated CampaignExperience object.
|
|
@@ -969,7 +971,8 @@ class SyncUsersService(SyncBaseService):
|
|
|
969
971
|
The Quickroll object with full details.
|
|
970
972
|
|
|
971
973
|
Raises:
|
|
972
|
-
NotFoundError: If the quickroll does not exist
|
|
974
|
+
NotFoundError: If the quickroll does not exist or does not belong to
|
|
975
|
+
``user_id``.
|
|
973
976
|
AuthorizationError: If you don't have access to the company.
|
|
974
977
|
"""
|
|
975
978
|
response = self._get(
|
|
@@ -1029,7 +1032,8 @@ class SyncUsersService(SyncBaseService):
|
|
|
1029
1032
|
The updated Quickroll object.
|
|
1030
1033
|
|
|
1031
1034
|
Raises:
|
|
1032
|
-
NotFoundError: If the quickroll does not exist
|
|
1035
|
+
NotFoundError: If the quickroll does not exist or does not belong to
|
|
1036
|
+
``user_id``.
|
|
1033
1037
|
AuthorizationError: If you don't have appropriate access.
|
|
1034
1038
|
RequestValidationError: If the input parameters fail client-side validation.
|
|
1035
1039
|
ValidationError: If the request data is invalid.
|
|
@@ -1053,7 +1057,8 @@ class SyncUsersService(SyncBaseService):
|
|
|
1053
1057
|
quickroll_id: The ID of the quickroll to delete.
|
|
1054
1058
|
|
|
1055
1059
|
Raises:
|
|
1056
|
-
NotFoundError: If the quickroll does not exist
|
|
1060
|
+
NotFoundError: If the quickroll does not exist or does not belong to
|
|
1061
|
+
``user_id``.
|
|
1057
1062
|
AuthorizationError: If you don't have appropriate access.
|
|
1058
1063
|
"""
|
|
1059
1064
|
self._delete(
|
|
@@ -212,6 +212,15 @@ class VClient:
|
|
|
212
212
|
"""Check if the client has been closed."""
|
|
213
213
|
return self._http.is_closed
|
|
214
214
|
|
|
215
|
+
def _set_api_key(self, api_key: str) -> None:
|
|
216
|
+
"""Send a new API key on every later request from this client and its services.
|
|
217
|
+
|
|
218
|
+
Args:
|
|
219
|
+
api_key: The API key to authenticate with from now on.
|
|
220
|
+
"""
|
|
221
|
+
self._config.api_key = api_key
|
|
222
|
+
self._http.headers[API_KEY_HEADER] = api_key
|
|
223
|
+
|
|
215
224
|
@property
|
|
216
225
|
def default_company_id(self) -> str | None:
|
|
217
226
|
"""Return the default company ID from config."""
|
|
@@ -106,4 +106,3 @@ BlueprintTraitOrderBy = Literal["NAME", "SHEET"]
|
|
|
106
106
|
TraitModifyCurrency = Literal["XP", "STARTING_POINTS", "NO_COST"]
|
|
107
107
|
TrackerType = Literal["COUNTER", "DAMAGE", "STAINS"]
|
|
108
108
|
TrackerAction = Literal["spend", "gain", "damage", "heal", "add_stain", "remove_stain", "reset"]
|
|
109
|
-
DamageType = Literal["SUPERFICIAL", "AGGRAVATED", "BASHING", "LETHAL"]
|
{valentina_python_client-3.4.0 → valentina_python_client-3.5.1}/src/vclient/models/__init__.py
RENAMED
|
@@ -51,7 +51,6 @@ from .character_trait import (
|
|
|
51
51
|
CharacterTraitSpecialtyUpdate,
|
|
52
52
|
CharacterTraitValueOptionsResponse,
|
|
53
53
|
CounterTracker,
|
|
54
|
-
DamageTracker,
|
|
55
54
|
Health,
|
|
56
55
|
HealthLevel,
|
|
57
56
|
HealthStateSet,
|
|
@@ -213,7 +212,6 @@ __all__ = [
|
|
|
213
212
|
"CompanyUpdate",
|
|
214
213
|
"CounterTracker",
|
|
215
214
|
"CreateAutogenerateDTO",
|
|
216
|
-
"DamageTracker",
|
|
217
215
|
"Developer",
|
|
218
216
|
"DeveloperCompanyPermission",
|
|
219
217
|
"DeveloperCreate",
|