valentina-python-client 1.4.0__tar.gz → 1.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-1.4.0 → valentina_python_client-1.5.0}/PKG-INFO +3 -9
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/README.md +2 -8
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/pyproject.toml +2 -1
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/__init__.py +1 -1
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/constants.py +2 -2
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/__init__.py +2 -2
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/shared.py +8 -8
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/campaign_book_chapters.py +61 -12
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/campaign_books.py +61 -12
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/campaigns.py +61 -12
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/characters.py +62 -13
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/users.py +61 -12
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/validate_constants.py +2 -2
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/LICENSE +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/client.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/config.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/endpoints.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/exceptions.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/books.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/campaigns.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/chapters.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/character_autogen.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/character_blueprint.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/character_trait.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/characters.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/companies.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/developers.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/diceroll.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/dictionary.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/global_admin.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/pagination.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/system.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/users.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/py.typed +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/registry.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/__init__.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/base.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/character_autogen.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/character_blueprint.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/character_traits.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/companies.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/developers.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/dicerolls.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/dictionary.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/global_admin.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/options.py +0 -0
- {valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/system.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: valentina-python-client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.5.0
|
|
4
4
|
Summary: Async Python client library for the Valentina Noir API
|
|
5
5
|
Author: Nate Landau
|
|
6
6
|
Author-email: Nate Landau <github@natenate.org>
|
|
@@ -38,11 +38,11 @@ Async Python client library for accessing the Valentina Noir API.
|
|
|
38
38
|
- **Idempotency support** - Optional automatic idempotency keys for safe retries
|
|
39
39
|
- **Rate limit handling** - Built-in support for automatic rate limit retries
|
|
40
40
|
|
|
41
|
-
This client is a supported and up-to-date reference implementation for the Valentina Noir API
|
|
41
|
+
This client is a supported and up-to-date reference implementation for the [Valentina Noir API](https://docs.valentina-noir.com).
|
|
42
42
|
|
|
43
43
|
## Documentation
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
The full documentation is available at https://natelandau.github.io/valentina-python-client/.
|
|
46
46
|
|
|
47
47
|
## Development Tools
|
|
48
48
|
|
|
@@ -65,9 +65,3 @@ The script reads configuration from (highest precedence first):
|
|
|
65
65
|
3. A `.env.secret` file in the project root
|
|
66
66
|
|
|
67
67
|
Exit codes: `0` = all constants match, `1` = mismatches found, `2` = missing configuration.
|
|
68
|
-
|
|
69
|
-
## Resources
|
|
70
|
-
|
|
71
|
-
- [Full Client Documentation](https://docs.valentina-noir.com/python-api-client/)
|
|
72
|
-
- [API Concepts](https://docs.valentina-noir.com/concepts/)
|
|
73
|
-
- [API Reference](https://api.valentina-noir.com/docs)
|
|
@@ -12,11 +12,11 @@ Async Python client library for accessing the Valentina Noir API.
|
|
|
12
12
|
- **Idempotency support** - Optional automatic idempotency keys for safe retries
|
|
13
13
|
- **Rate limit handling** - Built-in support for automatic rate limit retries
|
|
14
14
|
|
|
15
|
-
This client is a supported and up-to-date reference implementation for the Valentina Noir API
|
|
15
|
+
This client is a supported and up-to-date reference implementation for the [Valentina Noir API](https://docs.valentina-noir.com).
|
|
16
16
|
|
|
17
17
|
## Documentation
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
The full documentation is available at https://natelandau.github.io/valentina-python-client/.
|
|
20
20
|
|
|
21
21
|
## Development Tools
|
|
22
22
|
|
|
@@ -39,9 +39,3 @@ The script reads configuration from (highest precedence first):
|
|
|
39
39
|
3. A `.env.secret` file in the project root
|
|
40
40
|
|
|
41
41
|
Exit codes: `0` = all constants match, `1` = mismatches found, `2` = missing configuration.
|
|
42
|
-
|
|
43
|
-
## Resources
|
|
44
|
-
|
|
45
|
-
- [Full Client Documentation](https://docs.valentina-noir.com/python-api-client/)
|
|
46
|
-
- [API Concepts](https://docs.valentina-noir.com/concepts/)
|
|
47
|
-
- [API Reference](https://api.valentina-noir.com/docs)
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
name = "valentina-python-client"
|
|
11
11
|
readme = "README.md"
|
|
12
12
|
requires-python = ">=3.13"
|
|
13
|
-
version = "1.
|
|
13
|
+
version = "1.5.0"
|
|
14
14
|
|
|
15
15
|
[project.urls]
|
|
16
16
|
Homepage = "https://docs.valentina-noir.com/python-api-client/"
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"vulture>=2.14",
|
|
47
47
|
"yamllint>=1.38.0",
|
|
48
48
|
]
|
|
49
|
+
docs = ["zensical>=0.0.23"]
|
|
49
50
|
|
|
50
51
|
[tool.commitizen]
|
|
51
52
|
bump_message = "bump(release): v$current_version → v$new_version"
|
|
@@ -55,10 +55,10 @@ HunterEdgeType = Literal["ASSETS", "APTITUDES", "ENDOWMENTS"]
|
|
|
55
55
|
ManageCampaignPermission = Literal["UNRESTRICTED", "STORYTELLER"]
|
|
56
56
|
PermissionLevel = Literal["USER", "ADMIN", "OWNER", "REVOKE"]
|
|
57
57
|
RollResultType = Literal["SUCCESS", "FAILURE", "BOTCH", "CRITICAL", "OTHER"]
|
|
58
|
-
|
|
58
|
+
AssetParentType = Literal[
|
|
59
59
|
"character", "campaign", "campaignbook", "campaignchapter", "user", "company", "unknown"
|
|
60
60
|
]
|
|
61
|
-
|
|
61
|
+
AssetType = Literal["image", "text", "audio", "video", "document", "archive", "other"]
|
|
62
62
|
SpecialtyType = Literal["ACTION", "OTHER", "PASSIVE", "RITUAL", "SPELL"]
|
|
63
63
|
UserRole = Literal["ADMIN", "STORYTELLER", "PLAYER"]
|
|
64
64
|
WerewolfRenown = Literal["HONOR", "GLORY", "WISDOM"]
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/__init__.py
RENAMED
|
@@ -95,13 +95,13 @@ from .global_admin import (
|
|
|
95
95
|
)
|
|
96
96
|
from .pagination import PaginatedResponse
|
|
97
97
|
from .shared import (
|
|
98
|
+
Asset,
|
|
98
99
|
CharacterSpecialty,
|
|
99
100
|
NameDescriptionSubDocument,
|
|
100
101
|
Note,
|
|
101
102
|
NoteCreate,
|
|
102
103
|
NoteUpdate,
|
|
103
104
|
RollStatistics,
|
|
104
|
-
S3Asset,
|
|
105
105
|
Trait,
|
|
106
106
|
WerewolfGift,
|
|
107
107
|
WerewolfRite,
|
|
@@ -120,6 +120,7 @@ from .users import (
|
|
|
120
120
|
)
|
|
121
121
|
|
|
122
122
|
__all__ = [
|
|
123
|
+
"Asset",
|
|
123
124
|
"BookCreate",
|
|
124
125
|
"BookUpdate",
|
|
125
126
|
"Campaign",
|
|
@@ -183,7 +184,6 @@ __all__ = [
|
|
|
183
184
|
"QuickrollCreate",
|
|
184
185
|
"QuickrollUpdate",
|
|
185
186
|
"RollStatistics",
|
|
186
|
-
"S3Asset",
|
|
187
187
|
"SheetSection",
|
|
188
188
|
"SystemHealth",
|
|
189
189
|
"Trait",
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/shared.py
RENAMED
|
@@ -6,10 +6,10 @@ from typing import Annotated, Any
|
|
|
6
6
|
from pydantic import BaseModel, Field
|
|
7
7
|
|
|
8
8
|
from vclient.constants import (
|
|
9
|
+
AssetParentType,
|
|
10
|
+
AssetType,
|
|
9
11
|
CharacterClass,
|
|
10
12
|
GameVersion,
|
|
11
|
-
S3AssetParentType,
|
|
12
|
-
S3AssetType,
|
|
13
13
|
SpecialtyType,
|
|
14
14
|
WerewolfRenown,
|
|
15
15
|
)
|
|
@@ -31,22 +31,22 @@ class NameDescriptionSubDocument(BaseModel):
|
|
|
31
31
|
# -----------------------------------------------------------------------------
|
|
32
32
|
|
|
33
33
|
|
|
34
|
-
class
|
|
35
|
-
"""Response model for an
|
|
34
|
+
class Asset(BaseModel):
|
|
35
|
+
"""Response model for an asset.
|
|
36
36
|
|
|
37
|
-
Represents a file asset
|
|
37
|
+
Represents a file asset, including its URL and metadata.
|
|
38
38
|
"""
|
|
39
39
|
|
|
40
40
|
id: str
|
|
41
41
|
date_created: datetime
|
|
42
42
|
date_modified: datetime
|
|
43
|
-
asset_type:
|
|
43
|
+
asset_type: AssetType
|
|
44
44
|
mime_type: str
|
|
45
45
|
original_filename: str
|
|
46
46
|
public_url: str
|
|
47
47
|
uploaded_by: str
|
|
48
48
|
company_id: str
|
|
49
|
-
parent_type:
|
|
49
|
+
parent_type: AssetParentType | None = None
|
|
50
50
|
parent_id: str | None = None
|
|
51
51
|
|
|
52
52
|
|
|
@@ -197,13 +197,13 @@ class CharacterSpecialty(BaseModel):
|
|
|
197
197
|
|
|
198
198
|
|
|
199
199
|
__all__ = [
|
|
200
|
+
"Asset",
|
|
200
201
|
"CharacterSpecialty",
|
|
201
202
|
"NameDescriptionSubDocument",
|
|
202
203
|
"Note",
|
|
203
204
|
"NoteCreate",
|
|
204
205
|
"NoteUpdate",
|
|
205
206
|
"RollStatistics",
|
|
206
|
-
"S3Asset",
|
|
207
207
|
"Trait",
|
|
208
208
|
"WerewolfGift",
|
|
209
209
|
"WerewolfRite",
|
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
|
|
|
7
7
|
from vclient.constants import DEFAULT_PAGE_LIMIT
|
|
8
8
|
from vclient.endpoints import Endpoints
|
|
9
9
|
from vclient.models import (
|
|
10
|
+
Asset,
|
|
10
11
|
CampaignChapter,
|
|
11
12
|
ChapterCreate,
|
|
12
13
|
ChapterUpdate,
|
|
@@ -14,7 +15,6 @@ from vclient.models import (
|
|
|
14
15
|
NoteCreate,
|
|
15
16
|
NoteUpdate,
|
|
16
17
|
PaginatedResponse,
|
|
17
|
-
S3Asset,
|
|
18
18
|
_ChapterRenumber,
|
|
19
19
|
)
|
|
20
20
|
from vclient.services.base import BaseService
|
|
@@ -342,14 +342,14 @@ class ChaptersService(BaseService):
|
|
|
342
342
|
# Asset Methods
|
|
343
343
|
# -------------------------------------------------------------------------
|
|
344
344
|
|
|
345
|
-
async def
|
|
345
|
+
async def get_assets_page(
|
|
346
346
|
self,
|
|
347
347
|
chapter_id: str,
|
|
348
348
|
*,
|
|
349
349
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
350
350
|
offset: int = 0,
|
|
351
|
-
) -> PaginatedResponse[
|
|
352
|
-
"""Retrieve a paginated
|
|
351
|
+
) -> PaginatedResponse[Asset]:
|
|
352
|
+
"""Retrieve a paginated page of assets for a chapter.
|
|
353
353
|
|
|
354
354
|
Args:
|
|
355
355
|
chapter_id: The ID of the chapter whose assets to list.
|
|
@@ -357,7 +357,7 @@ class ChaptersService(BaseService):
|
|
|
357
357
|
offset: Number of items to skip from the beginning (default 0).
|
|
358
358
|
|
|
359
359
|
Returns:
|
|
360
|
-
A PaginatedResponse containing
|
|
360
|
+
A PaginatedResponse containing Asset objects and pagination metadata.
|
|
361
361
|
|
|
362
362
|
Raises:
|
|
363
363
|
NotFoundError: If the chapter does not exist.
|
|
@@ -365,16 +365,65 @@ class ChaptersService(BaseService):
|
|
|
365
365
|
"""
|
|
366
366
|
return await self._get_paginated_as(
|
|
367
367
|
self._format_endpoint(Endpoints.BOOK_CHAPTER_ASSETS, chapter_id=chapter_id),
|
|
368
|
-
|
|
368
|
+
Asset,
|
|
369
369
|
limit=limit,
|
|
370
370
|
offset=offset,
|
|
371
371
|
)
|
|
372
372
|
|
|
373
|
+
async def list_all_assets(
|
|
374
|
+
self,
|
|
375
|
+
chapter_id: str,
|
|
376
|
+
) -> list[Asset]:
|
|
377
|
+
"""Retrieve all assets for a chapter.
|
|
378
|
+
|
|
379
|
+
Automatically paginates through all results. Use `get_assets_page()` for paginated
|
|
380
|
+
access or `iter_all_assets()` for memory-efficient streaming of large datasets.
|
|
381
|
+
|
|
382
|
+
Args:
|
|
383
|
+
chapter_id: The ID of the chapter whose assets to list.
|
|
384
|
+
|
|
385
|
+
Returns:
|
|
386
|
+
A list of all Asset objects.
|
|
387
|
+
|
|
388
|
+
Raises:
|
|
389
|
+
NotFoundError: If the chapter does not exist.
|
|
390
|
+
AuthorizationError: If you don't have access.
|
|
391
|
+
"""
|
|
392
|
+
return [asset async for asset in self.iter_all_assets(chapter_id)]
|
|
393
|
+
|
|
394
|
+
async def iter_all_assets(
|
|
395
|
+
self,
|
|
396
|
+
chapter_id: str,
|
|
397
|
+
*,
|
|
398
|
+
limit: int = 100,
|
|
399
|
+
) -> AsyncIterator[Asset]:
|
|
400
|
+
"""Iterate through all assets for a chapter.
|
|
401
|
+
|
|
402
|
+
Yields individual assets, automatically fetching subsequent pages until
|
|
403
|
+
all items have been retrieved.
|
|
404
|
+
|
|
405
|
+
Args:
|
|
406
|
+
chapter_id: The ID of the chapter whose assets to iterate.
|
|
407
|
+
limit: Items per page (default 100 for efficiency).
|
|
408
|
+
|
|
409
|
+
Yields:
|
|
410
|
+
Individual Asset objects.
|
|
411
|
+
|
|
412
|
+
Example:
|
|
413
|
+
>>> async for asset in chapters.iter_all_assets("chapter_id"):
|
|
414
|
+
... print(asset.original_filename)
|
|
415
|
+
"""
|
|
416
|
+
async for item in self._iter_all_pages(
|
|
417
|
+
self._format_endpoint(Endpoints.BOOK_CHAPTER_ASSETS, chapter_id=chapter_id),
|
|
418
|
+
limit=limit,
|
|
419
|
+
):
|
|
420
|
+
yield Asset.model_validate(item)
|
|
421
|
+
|
|
373
422
|
async def get_asset(
|
|
374
423
|
self,
|
|
375
424
|
chapter_id: str,
|
|
376
425
|
asset_id: str,
|
|
377
|
-
) ->
|
|
426
|
+
) -> Asset:
|
|
378
427
|
"""Retrieve details of a specific asset including its URL and metadata.
|
|
379
428
|
|
|
380
429
|
Args:
|
|
@@ -382,7 +431,7 @@ class ChaptersService(BaseService):
|
|
|
382
431
|
asset_id: The ID of the asset to retrieve.
|
|
383
432
|
|
|
384
433
|
Returns:
|
|
385
|
-
The
|
|
434
|
+
The Asset object with full details.
|
|
386
435
|
|
|
387
436
|
Raises:
|
|
388
437
|
NotFoundError: If the asset does not exist.
|
|
@@ -393,7 +442,7 @@ class ChaptersService(BaseService):
|
|
|
393
442
|
Endpoints.BOOK_CHAPTER_ASSET, chapter_id=chapter_id, asset_id=asset_id
|
|
394
443
|
)
|
|
395
444
|
)
|
|
396
|
-
return
|
|
445
|
+
return Asset.model_validate(response.json())
|
|
397
446
|
|
|
398
447
|
async def upload_asset(
|
|
399
448
|
self,
|
|
@@ -401,7 +450,7 @@ class ChaptersService(BaseService):
|
|
|
401
450
|
filename: str,
|
|
402
451
|
content: bytes,
|
|
403
452
|
content_type: str | None = None,
|
|
404
|
-
) ->
|
|
453
|
+
) -> Asset:
|
|
405
454
|
"""Upload a new asset for a chapter.
|
|
406
455
|
|
|
407
456
|
Uploads a file to S3 storage and associates it with the chapter.
|
|
@@ -413,7 +462,7 @@ class ChaptersService(BaseService):
|
|
|
413
462
|
content_type: The MIME type of the file. If not provided, inferred from filename.
|
|
414
463
|
|
|
415
464
|
Returns:
|
|
416
|
-
The created
|
|
465
|
+
The created Asset object with the public URL and metadata.
|
|
417
466
|
|
|
418
467
|
Raises:
|
|
419
468
|
NotFoundError: If the chapter does not exist.
|
|
@@ -427,7 +476,7 @@ class ChaptersService(BaseService):
|
|
|
427
476
|
self._format_endpoint(Endpoints.BOOK_CHAPTER_ASSET_UPLOAD, chapter_id=chapter_id),
|
|
428
477
|
file=(filename, content, content_type),
|
|
429
478
|
)
|
|
430
|
-
return
|
|
479
|
+
return Asset.model_validate(response.json())
|
|
431
480
|
|
|
432
481
|
async def delete_asset(
|
|
433
482
|
self,
|
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
|
|
|
7
7
|
from vclient.constants import DEFAULT_PAGE_LIMIT
|
|
8
8
|
from vclient.endpoints import Endpoints
|
|
9
9
|
from vclient.models import (
|
|
10
|
+
Asset,
|
|
10
11
|
BookCreate,
|
|
11
12
|
BookUpdate,
|
|
12
13
|
CampaignBook,
|
|
@@ -14,7 +15,6 @@ from vclient.models import (
|
|
|
14
15
|
NoteCreate,
|
|
15
16
|
NoteUpdate,
|
|
16
17
|
PaginatedResponse,
|
|
17
|
-
S3Asset,
|
|
18
18
|
_BookRenumber,
|
|
19
19
|
)
|
|
20
20
|
from vclient.services.base import BaseService
|
|
@@ -438,14 +438,14 @@ class BooksService(BaseService):
|
|
|
438
438
|
# Asset Methods
|
|
439
439
|
# -------------------------------------------------------------------------
|
|
440
440
|
|
|
441
|
-
async def
|
|
441
|
+
async def get_assets_page(
|
|
442
442
|
self,
|
|
443
443
|
book_id: str,
|
|
444
444
|
*,
|
|
445
445
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
446
446
|
offset: int = 0,
|
|
447
|
-
) -> PaginatedResponse[
|
|
448
|
-
"""Retrieve a paginated
|
|
447
|
+
) -> PaginatedResponse[Asset]:
|
|
448
|
+
"""Retrieve a paginated page of assets for a book.
|
|
449
449
|
|
|
450
450
|
Args:
|
|
451
451
|
book_id: The ID of the book whose assets to list.
|
|
@@ -453,7 +453,7 @@ class BooksService(BaseService):
|
|
|
453
453
|
offset: Number of items to skip from the beginning (default 0).
|
|
454
454
|
|
|
455
455
|
Returns:
|
|
456
|
-
A PaginatedResponse containing
|
|
456
|
+
A PaginatedResponse containing Asset objects and pagination metadata.
|
|
457
457
|
|
|
458
458
|
Raises:
|
|
459
459
|
NotFoundError: If the book does not exist.
|
|
@@ -461,16 +461,65 @@ class BooksService(BaseService):
|
|
|
461
461
|
"""
|
|
462
462
|
return await self._get_paginated_as(
|
|
463
463
|
self._format_endpoint(Endpoints.BOOK_ASSETS, book_id=book_id),
|
|
464
|
-
|
|
464
|
+
Asset,
|
|
465
465
|
limit=limit,
|
|
466
466
|
offset=offset,
|
|
467
467
|
)
|
|
468
468
|
|
|
469
|
+
async def list_all_assets(
|
|
470
|
+
self,
|
|
471
|
+
book_id: str,
|
|
472
|
+
) -> list[Asset]:
|
|
473
|
+
"""Retrieve all assets for a book.
|
|
474
|
+
|
|
475
|
+
Automatically paginates through all results. Use `get_assets_page()` for paginated
|
|
476
|
+
access or `iter_all_assets()` for memory-efficient streaming of large datasets.
|
|
477
|
+
|
|
478
|
+
Args:
|
|
479
|
+
book_id: The ID of the book whose assets to list.
|
|
480
|
+
|
|
481
|
+
Returns:
|
|
482
|
+
A list of all Asset objects.
|
|
483
|
+
|
|
484
|
+
Raises:
|
|
485
|
+
NotFoundError: If the book does not exist.
|
|
486
|
+
AuthorizationError: If you don't have access.
|
|
487
|
+
"""
|
|
488
|
+
return [asset async for asset in self.iter_all_assets(book_id)]
|
|
489
|
+
|
|
490
|
+
async def iter_all_assets(
|
|
491
|
+
self,
|
|
492
|
+
book_id: str,
|
|
493
|
+
*,
|
|
494
|
+
limit: int = 100,
|
|
495
|
+
) -> AsyncIterator[Asset]:
|
|
496
|
+
"""Iterate through all assets for a book.
|
|
497
|
+
|
|
498
|
+
Yields individual assets, automatically fetching subsequent pages until
|
|
499
|
+
all items have been retrieved.
|
|
500
|
+
|
|
501
|
+
Args:
|
|
502
|
+
book_id: The ID of the book whose assets to iterate.
|
|
503
|
+
limit: Items per page (default 100 for efficiency).
|
|
504
|
+
|
|
505
|
+
Yields:
|
|
506
|
+
Individual Asset objects.
|
|
507
|
+
|
|
508
|
+
Example:
|
|
509
|
+
>>> async for asset in books.iter_all_assets("book_id"):
|
|
510
|
+
... print(asset.original_filename)
|
|
511
|
+
"""
|
|
512
|
+
async for item in self._iter_all_pages(
|
|
513
|
+
self._format_endpoint(Endpoints.BOOK_ASSETS, book_id=book_id),
|
|
514
|
+
limit=limit,
|
|
515
|
+
):
|
|
516
|
+
yield Asset.model_validate(item)
|
|
517
|
+
|
|
469
518
|
async def get_asset(
|
|
470
519
|
self,
|
|
471
520
|
book_id: str,
|
|
472
521
|
asset_id: str,
|
|
473
|
-
) ->
|
|
522
|
+
) -> Asset:
|
|
474
523
|
"""Retrieve details of a specific asset including its URL and metadata.
|
|
475
524
|
|
|
476
525
|
Args:
|
|
@@ -478,7 +527,7 @@ class BooksService(BaseService):
|
|
|
478
527
|
asset_id: The ID of the asset to retrieve.
|
|
479
528
|
|
|
480
529
|
Returns:
|
|
481
|
-
The
|
|
530
|
+
The Asset object with full details.
|
|
482
531
|
|
|
483
532
|
Raises:
|
|
484
533
|
NotFoundError: If the asset does not exist.
|
|
@@ -487,7 +536,7 @@ class BooksService(BaseService):
|
|
|
487
536
|
response = await self._get(
|
|
488
537
|
self._format_endpoint(Endpoints.BOOK_ASSET, book_id=book_id, asset_id=asset_id)
|
|
489
538
|
)
|
|
490
|
-
return
|
|
539
|
+
return Asset.model_validate(response.json())
|
|
491
540
|
|
|
492
541
|
async def upload_asset(
|
|
493
542
|
self,
|
|
@@ -495,7 +544,7 @@ class BooksService(BaseService):
|
|
|
495
544
|
filename: str,
|
|
496
545
|
content: bytes,
|
|
497
546
|
content_type: str | None = None,
|
|
498
|
-
) ->
|
|
547
|
+
) -> Asset:
|
|
499
548
|
"""Upload a new asset for a book.
|
|
500
549
|
|
|
501
550
|
Uploads a file to S3 storage and associates it with the book.
|
|
@@ -507,7 +556,7 @@ class BooksService(BaseService):
|
|
|
507
556
|
content_type: The MIME type of the file. If not provided, inferred from filename.
|
|
508
557
|
|
|
509
558
|
Returns:
|
|
510
|
-
The created
|
|
559
|
+
The created Asset object with the public URL and metadata.
|
|
511
560
|
|
|
512
561
|
Raises:
|
|
513
562
|
NotFoundError: If the book does not exist.
|
|
@@ -521,7 +570,7 @@ class BooksService(BaseService):
|
|
|
521
570
|
self._format_endpoint(Endpoints.BOOK_ASSET_UPLOAD, book_id=book_id),
|
|
522
571
|
file=(filename, content, content_type),
|
|
523
572
|
)
|
|
524
|
-
return
|
|
573
|
+
return Asset.model_validate(response.json())
|
|
525
574
|
|
|
526
575
|
async def delete_asset(
|
|
527
576
|
self,
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/campaigns.py
RENAMED
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
|
|
|
7
7
|
from vclient.constants import DEFAULT_PAGE_LIMIT
|
|
8
8
|
from vclient.endpoints import Endpoints
|
|
9
9
|
from vclient.models import (
|
|
10
|
+
Asset,
|
|
10
11
|
Campaign,
|
|
11
12
|
CampaignCreate,
|
|
12
13
|
CampaignUpdate,
|
|
@@ -15,7 +16,6 @@ from vclient.models import (
|
|
|
15
16
|
NoteUpdate,
|
|
16
17
|
PaginatedResponse,
|
|
17
18
|
RollStatistics,
|
|
18
|
-
S3Asset,
|
|
19
19
|
)
|
|
20
20
|
from vclient.services.base import BaseService
|
|
21
21
|
|
|
@@ -249,14 +249,14 @@ class CampaignsService(BaseService):
|
|
|
249
249
|
# Asset Methods
|
|
250
250
|
# -------------------------------------------------------------------------
|
|
251
251
|
|
|
252
|
-
async def
|
|
252
|
+
async def get_assets_page(
|
|
253
253
|
self,
|
|
254
254
|
campaign_id: str,
|
|
255
255
|
*,
|
|
256
256
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
257
257
|
offset: int = 0,
|
|
258
|
-
) -> PaginatedResponse[
|
|
259
|
-
"""Retrieve a paginated
|
|
258
|
+
) -> PaginatedResponse[Asset]:
|
|
259
|
+
"""Retrieve a paginated page of assets for a campaign.
|
|
260
260
|
|
|
261
261
|
Args:
|
|
262
262
|
campaign_id: The ID of the campaign whose assets to list.
|
|
@@ -264,7 +264,7 @@ class CampaignsService(BaseService):
|
|
|
264
264
|
offset: Number of items to skip from the beginning (default 0).
|
|
265
265
|
|
|
266
266
|
Returns:
|
|
267
|
-
A PaginatedResponse containing
|
|
267
|
+
A PaginatedResponse containing Asset objects and pagination metadata.
|
|
268
268
|
|
|
269
269
|
Raises:
|
|
270
270
|
NotFoundError: If the campaign does not exist.
|
|
@@ -272,16 +272,65 @@ class CampaignsService(BaseService):
|
|
|
272
272
|
"""
|
|
273
273
|
return await self._get_paginated_as(
|
|
274
274
|
self._format_endpoint(Endpoints.CAMPAIGN_ASSETS, campaign_id=campaign_id),
|
|
275
|
-
|
|
275
|
+
Asset,
|
|
276
276
|
limit=limit,
|
|
277
277
|
offset=offset,
|
|
278
278
|
)
|
|
279
279
|
|
|
280
|
+
async def list_all_assets(
|
|
281
|
+
self,
|
|
282
|
+
campaign_id: str,
|
|
283
|
+
) -> list[Asset]:
|
|
284
|
+
"""Retrieve all assets for a campaign.
|
|
285
|
+
|
|
286
|
+
Automatically paginates through all results. Use `get_assets_page()` for paginated
|
|
287
|
+
access or `iter_all_assets()` for memory-efficient streaming of large datasets.
|
|
288
|
+
|
|
289
|
+
Args:
|
|
290
|
+
campaign_id: The ID of the campaign whose assets to list.
|
|
291
|
+
|
|
292
|
+
Returns:
|
|
293
|
+
A list of all Asset objects.
|
|
294
|
+
|
|
295
|
+
Raises:
|
|
296
|
+
NotFoundError: If the campaign does not exist.
|
|
297
|
+
AuthorizationError: If you don't have access.
|
|
298
|
+
"""
|
|
299
|
+
return [asset async for asset in self.iter_all_assets(campaign_id)]
|
|
300
|
+
|
|
301
|
+
async def iter_all_assets(
|
|
302
|
+
self,
|
|
303
|
+
campaign_id: str,
|
|
304
|
+
*,
|
|
305
|
+
limit: int = 100,
|
|
306
|
+
) -> AsyncIterator[Asset]:
|
|
307
|
+
"""Iterate through all assets for a campaign.
|
|
308
|
+
|
|
309
|
+
Yields individual assets, automatically fetching subsequent pages until
|
|
310
|
+
all items have been retrieved.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
campaign_id: The ID of the campaign whose assets to iterate.
|
|
314
|
+
limit: Items per page (default 100 for efficiency).
|
|
315
|
+
|
|
316
|
+
Yields:
|
|
317
|
+
Individual Asset objects.
|
|
318
|
+
|
|
319
|
+
Example:
|
|
320
|
+
>>> async for asset in campaigns.iter_all_assets("campaign_id"):
|
|
321
|
+
... print(asset.original_filename)
|
|
322
|
+
"""
|
|
323
|
+
async for item in self._iter_all_pages(
|
|
324
|
+
self._format_endpoint(Endpoints.CAMPAIGN_ASSETS, campaign_id=campaign_id),
|
|
325
|
+
limit=limit,
|
|
326
|
+
):
|
|
327
|
+
yield Asset.model_validate(item)
|
|
328
|
+
|
|
280
329
|
async def get_asset(
|
|
281
330
|
self,
|
|
282
331
|
campaign_id: str,
|
|
283
332
|
asset_id: str,
|
|
284
|
-
) ->
|
|
333
|
+
) -> Asset:
|
|
285
334
|
"""Retrieve details of a specific asset including its URL and metadata.
|
|
286
335
|
|
|
287
336
|
Args:
|
|
@@ -289,7 +338,7 @@ class CampaignsService(BaseService):
|
|
|
289
338
|
asset_id: The ID of the asset to retrieve.
|
|
290
339
|
|
|
291
340
|
Returns:
|
|
292
|
-
The
|
|
341
|
+
The Asset object with full details.
|
|
293
342
|
|
|
294
343
|
Raises:
|
|
295
344
|
NotFoundError: If the asset does not exist.
|
|
@@ -300,7 +349,7 @@ class CampaignsService(BaseService):
|
|
|
300
349
|
Endpoints.CAMPAIGN_ASSET, campaign_id=campaign_id, asset_id=asset_id
|
|
301
350
|
)
|
|
302
351
|
)
|
|
303
|
-
return
|
|
352
|
+
return Asset.model_validate(response.json())
|
|
304
353
|
|
|
305
354
|
async def delete_asset(
|
|
306
355
|
self,
|
|
@@ -331,7 +380,7 @@ class CampaignsService(BaseService):
|
|
|
331
380
|
filename: str,
|
|
332
381
|
content: bytes,
|
|
333
382
|
content_type: str | None = None,
|
|
334
|
-
) ->
|
|
383
|
+
) -> Asset:
|
|
335
384
|
"""Upload a new asset for a campaign.
|
|
336
385
|
|
|
337
386
|
Uploads a file to S3 storage and associates it with the campaign.
|
|
@@ -343,7 +392,7 @@ class CampaignsService(BaseService):
|
|
|
343
392
|
content_type: The MIME type of the file. If not provided, inferred from filename.
|
|
344
393
|
|
|
345
394
|
Returns:
|
|
346
|
-
The created
|
|
395
|
+
The created Asset object with the public URL and metadata.
|
|
347
396
|
|
|
348
397
|
Raises:
|
|
349
398
|
NotFoundError: If the campaign does not exist.
|
|
@@ -357,7 +406,7 @@ class CampaignsService(BaseService):
|
|
|
357
406
|
self._format_endpoint(Endpoints.CAMPAIGN_ASSET_UPLOAD, campaign_id=campaign_id),
|
|
358
407
|
file=(filename, content, content_type),
|
|
359
408
|
)
|
|
360
|
-
return
|
|
409
|
+
return Asset.model_validate(response.json())
|
|
361
410
|
|
|
362
411
|
# -------------------------------------------------------------------------
|
|
363
412
|
# Notes Methods
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/characters.py
RENAMED
|
@@ -12,6 +12,7 @@ from vclient.constants import (
|
|
|
12
12
|
)
|
|
13
13
|
from vclient.endpoints import Endpoints
|
|
14
14
|
from vclient.models import (
|
|
15
|
+
Asset,
|
|
15
16
|
Character,
|
|
16
17
|
CharacterCreate,
|
|
17
18
|
CharacterUpdate,
|
|
@@ -25,7 +26,6 @@ from vclient.models import (
|
|
|
25
26
|
PaginatedResponse,
|
|
26
27
|
Perk,
|
|
27
28
|
RollStatistics,
|
|
28
|
-
S3Asset,
|
|
29
29
|
WerewolfGift,
|
|
30
30
|
WerewolfRite,
|
|
31
31
|
)
|
|
@@ -333,14 +333,14 @@ class CharactersService(BaseService):
|
|
|
333
333
|
# Asset Methods
|
|
334
334
|
# -------------------------------------------------------------------------
|
|
335
335
|
|
|
336
|
-
async def
|
|
336
|
+
async def get_assets_page(
|
|
337
337
|
self,
|
|
338
338
|
character_id: str,
|
|
339
339
|
*,
|
|
340
340
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
341
341
|
offset: int = 0,
|
|
342
|
-
) -> PaginatedResponse[
|
|
343
|
-
"""Retrieve a paginated
|
|
342
|
+
) -> PaginatedResponse[Asset]:
|
|
343
|
+
"""Retrieve a paginated page of assets for a character.
|
|
344
344
|
|
|
345
345
|
Args:
|
|
346
346
|
character_id: The ID of the character whose assets to list.
|
|
@@ -348,24 +348,73 @@ class CharactersService(BaseService):
|
|
|
348
348
|
offset: Number of items to skip from the beginning (default 0).
|
|
349
349
|
|
|
350
350
|
Returns:
|
|
351
|
-
A PaginatedResponse containing
|
|
351
|
+
A PaginatedResponse containing Asset objects and pagination metadata.
|
|
352
352
|
|
|
353
353
|
Raises:
|
|
354
|
-
NotFoundError: If the
|
|
354
|
+
NotFoundError: If the character does not exist.
|
|
355
355
|
AuthorizationError: If you don't have access.
|
|
356
356
|
"""
|
|
357
357
|
return await self._get_paginated_as(
|
|
358
358
|
self._format_endpoint(Endpoints.CHARACTER_ASSETS, character_id=character_id),
|
|
359
|
-
|
|
359
|
+
Asset,
|
|
360
360
|
limit=limit,
|
|
361
361
|
offset=offset,
|
|
362
362
|
)
|
|
363
363
|
|
|
364
|
+
async def list_all_assets(
|
|
365
|
+
self,
|
|
366
|
+
character_id: str,
|
|
367
|
+
) -> list[Asset]:
|
|
368
|
+
"""Retrieve all assets for a character.
|
|
369
|
+
|
|
370
|
+
Automatically paginates through all results. Use `get_assets_page()` for paginated
|
|
371
|
+
access or `iter_all_assets()` for memory-efficient streaming of large datasets.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
character_id: The ID of the character whose assets to list.
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
A list of all Asset objects.
|
|
378
|
+
|
|
379
|
+
Raises:
|
|
380
|
+
NotFoundError: If the character does not exist.
|
|
381
|
+
AuthorizationError: If you don't have access.
|
|
382
|
+
"""
|
|
383
|
+
return [asset async for asset in self.iter_all_assets(character_id)]
|
|
384
|
+
|
|
385
|
+
async def iter_all_assets(
|
|
386
|
+
self,
|
|
387
|
+
character_id: str,
|
|
388
|
+
*,
|
|
389
|
+
limit: int = 100,
|
|
390
|
+
) -> AsyncIterator[Asset]:
|
|
391
|
+
"""Iterate through all assets for a character.
|
|
392
|
+
|
|
393
|
+
Yields individual assets, automatically fetching subsequent pages until
|
|
394
|
+
all items have been retrieved.
|
|
395
|
+
|
|
396
|
+
Args:
|
|
397
|
+
character_id: The ID of the character whose assets to iterate.
|
|
398
|
+
limit: Items per page (default 100 for efficiency).
|
|
399
|
+
|
|
400
|
+
Yields:
|
|
401
|
+
Individual Asset objects.
|
|
402
|
+
|
|
403
|
+
Example:
|
|
404
|
+
>>> async for asset in characters.iter_all_assets("character_id"):
|
|
405
|
+
... print(asset.original_filename)
|
|
406
|
+
"""
|
|
407
|
+
async for item in self._iter_all_pages(
|
|
408
|
+
self._format_endpoint(Endpoints.CHARACTER_ASSETS, character_id=character_id),
|
|
409
|
+
limit=limit,
|
|
410
|
+
):
|
|
411
|
+
yield Asset.model_validate(item)
|
|
412
|
+
|
|
364
413
|
async def get_asset(
|
|
365
414
|
self,
|
|
366
415
|
character_id: str,
|
|
367
416
|
asset_id: str,
|
|
368
|
-
) ->
|
|
417
|
+
) -> Asset:
|
|
369
418
|
"""Retrieve details of a specific asset including its URL and metadata.
|
|
370
419
|
|
|
371
420
|
Args:
|
|
@@ -373,7 +422,7 @@ class CharactersService(BaseService):
|
|
|
373
422
|
asset_id: The ID of the asset to retrieve.
|
|
374
423
|
|
|
375
424
|
Returns:
|
|
376
|
-
The
|
|
425
|
+
The Asset object with full details.
|
|
377
426
|
|
|
378
427
|
Raises:
|
|
379
428
|
NotFoundError: If the asset does not exist.
|
|
@@ -384,7 +433,7 @@ class CharactersService(BaseService):
|
|
|
384
433
|
Endpoints.CHARACTER_ASSET, character_id=character_id, asset_id=asset_id
|
|
385
434
|
)
|
|
386
435
|
)
|
|
387
|
-
return
|
|
436
|
+
return Asset.model_validate(response.json())
|
|
388
437
|
|
|
389
438
|
async def delete_asset(
|
|
390
439
|
self,
|
|
@@ -415,7 +464,7 @@ class CharactersService(BaseService):
|
|
|
415
464
|
filename: str,
|
|
416
465
|
content: bytes,
|
|
417
466
|
content_type: str | None = None,
|
|
418
|
-
) ->
|
|
467
|
+
) -> Asset:
|
|
419
468
|
"""Upload a new asset for a campaign.
|
|
420
469
|
|
|
421
470
|
Uploads a file to S3 storage and associates it with the campaign.
|
|
@@ -427,7 +476,7 @@ class CharactersService(BaseService):
|
|
|
427
476
|
content_type: The MIME type of the file. If not provided, inferred from filename.
|
|
428
477
|
|
|
429
478
|
Returns:
|
|
430
|
-
The created
|
|
479
|
+
The created Asset object with the public URL and metadata.
|
|
431
480
|
|
|
432
481
|
Raises:
|
|
433
482
|
NotFoundError: If the character does not exist.
|
|
@@ -441,7 +490,7 @@ class CharactersService(BaseService):
|
|
|
441
490
|
self._format_endpoint(Endpoints.CHARACTER_ASSET_UPLOAD, character_id=character_id),
|
|
442
491
|
file=(filename, content, content_type),
|
|
443
492
|
)
|
|
444
|
-
return
|
|
493
|
+
return Asset.model_validate(response.json())
|
|
445
494
|
|
|
446
495
|
# -------------------------------------------------------------------------
|
|
447
496
|
# Notes Methods
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/users.py
RENAMED
|
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
|
|
|
7
7
|
from vclient.constants import DEFAULT_PAGE_LIMIT, UserRole
|
|
8
8
|
from vclient.endpoints import Endpoints
|
|
9
9
|
from vclient.models import (
|
|
10
|
+
Asset,
|
|
10
11
|
CampaignExperience,
|
|
11
12
|
Note,
|
|
12
13
|
NoteCreate,
|
|
@@ -16,7 +17,6 @@ from vclient.models import (
|
|
|
16
17
|
QuickrollCreate,
|
|
17
18
|
QuickrollUpdate,
|
|
18
19
|
RollStatistics,
|
|
19
|
-
S3Asset,
|
|
20
20
|
User,
|
|
21
21
|
UserCreate,
|
|
22
22
|
UserUpdate,
|
|
@@ -275,14 +275,14 @@ class UsersService(BaseService):
|
|
|
275
275
|
# Asset Methods
|
|
276
276
|
# -------------------------------------------------------------------------
|
|
277
277
|
|
|
278
|
-
async def
|
|
278
|
+
async def get_assets_page(
|
|
279
279
|
self,
|
|
280
280
|
user_id: str,
|
|
281
281
|
*,
|
|
282
282
|
limit: int = DEFAULT_PAGE_LIMIT,
|
|
283
283
|
offset: int = 0,
|
|
284
|
-
) -> PaginatedResponse[
|
|
285
|
-
"""Retrieve a paginated
|
|
284
|
+
) -> PaginatedResponse[Asset]:
|
|
285
|
+
"""Retrieve a paginated page of assets for a user.
|
|
286
286
|
|
|
287
287
|
Args:
|
|
288
288
|
user_id: The ID of the user whose assets to list.
|
|
@@ -290,7 +290,7 @@ class UsersService(BaseService):
|
|
|
290
290
|
offset: Number of items to skip from the beginning (default 0).
|
|
291
291
|
|
|
292
292
|
Returns:
|
|
293
|
-
A PaginatedResponse containing
|
|
293
|
+
A PaginatedResponse containing Asset objects and pagination metadata.
|
|
294
294
|
|
|
295
295
|
Raises:
|
|
296
296
|
NotFoundError: If the user does not exist.
|
|
@@ -298,16 +298,65 @@ class UsersService(BaseService):
|
|
|
298
298
|
"""
|
|
299
299
|
return await self._get_paginated_as(
|
|
300
300
|
self._format_endpoint(Endpoints.USER_ASSETS, user_id=user_id),
|
|
301
|
-
|
|
301
|
+
Asset,
|
|
302
302
|
limit=limit,
|
|
303
303
|
offset=offset,
|
|
304
304
|
)
|
|
305
305
|
|
|
306
|
+
async def list_all_assets(
|
|
307
|
+
self,
|
|
308
|
+
user_id: str,
|
|
309
|
+
) -> list[Asset]:
|
|
310
|
+
"""Retrieve all assets for a user.
|
|
311
|
+
|
|
312
|
+
Automatically paginates through all results. Use `get_assets_page()` for paginated
|
|
313
|
+
access or `iter_all_assets()` for memory-efficient streaming of large datasets.
|
|
314
|
+
|
|
315
|
+
Args:
|
|
316
|
+
user_id: The ID of the user whose assets to list.
|
|
317
|
+
|
|
318
|
+
Returns:
|
|
319
|
+
A list of all Asset objects.
|
|
320
|
+
|
|
321
|
+
Raises:
|
|
322
|
+
NotFoundError: If the user does not exist.
|
|
323
|
+
AuthorizationError: If you don't have access to the company.
|
|
324
|
+
"""
|
|
325
|
+
return [asset async for asset in self.iter_all_assets(user_id)]
|
|
326
|
+
|
|
327
|
+
async def iter_all_assets(
|
|
328
|
+
self,
|
|
329
|
+
user_id: str,
|
|
330
|
+
*,
|
|
331
|
+
limit: int = 100,
|
|
332
|
+
) -> AsyncIterator[Asset]:
|
|
333
|
+
"""Iterate through all assets for a user.
|
|
334
|
+
|
|
335
|
+
Yields individual assets, automatically fetching subsequent pages until
|
|
336
|
+
all items have been retrieved.
|
|
337
|
+
|
|
338
|
+
Args:
|
|
339
|
+
user_id: The ID of the user whose assets to iterate.
|
|
340
|
+
limit: Items per page (default 100 for efficiency).
|
|
341
|
+
|
|
342
|
+
Yields:
|
|
343
|
+
Individual Asset objects.
|
|
344
|
+
|
|
345
|
+
Example:
|
|
346
|
+
>>> async for asset in users.iter_all_assets("user_id"):
|
|
347
|
+
... print(asset.original_filename)
|
|
348
|
+
"""
|
|
349
|
+
async for item in self._iter_all_pages(
|
|
350
|
+
self._format_endpoint(Endpoints.USER_ASSETS, user_id=user_id),
|
|
351
|
+
limit=limit,
|
|
352
|
+
):
|
|
353
|
+
yield Asset.model_validate(item)
|
|
354
|
+
|
|
306
355
|
async def get_asset(
|
|
307
356
|
self,
|
|
308
357
|
user_id: str,
|
|
309
358
|
asset_id: str,
|
|
310
|
-
) ->
|
|
359
|
+
) -> Asset:
|
|
311
360
|
"""Retrieve details of a specific asset including its URL and metadata.
|
|
312
361
|
|
|
313
362
|
Args:
|
|
@@ -315,7 +364,7 @@ class UsersService(BaseService):
|
|
|
315
364
|
asset_id: The ID of the asset to retrieve.
|
|
316
365
|
|
|
317
366
|
Returns:
|
|
318
|
-
The
|
|
367
|
+
The Asset object with full details.
|
|
319
368
|
|
|
320
369
|
Raises:
|
|
321
370
|
NotFoundError: If the asset does not exist.
|
|
@@ -324,7 +373,7 @@ class UsersService(BaseService):
|
|
|
324
373
|
response = await self._get(
|
|
325
374
|
self._format_endpoint(Endpoints.USER_ASSET, user_id=user_id, asset_id=asset_id)
|
|
326
375
|
)
|
|
327
|
-
return
|
|
376
|
+
return Asset.model_validate(response.json())
|
|
328
377
|
|
|
329
378
|
async def delete_asset(
|
|
330
379
|
self,
|
|
@@ -353,7 +402,7 @@ class UsersService(BaseService):
|
|
|
353
402
|
filename: str,
|
|
354
403
|
content: bytes,
|
|
355
404
|
content_type: str | None = None,
|
|
356
|
-
) ->
|
|
405
|
+
) -> Asset:
|
|
357
406
|
"""Upload a new asset for a user.
|
|
358
407
|
|
|
359
408
|
Uploads a file to S3 storage and associates it with the user.
|
|
@@ -365,7 +414,7 @@ class UsersService(BaseService):
|
|
|
365
414
|
content_type: The MIME type of the file. If not provided, inferred from filename.
|
|
366
415
|
|
|
367
416
|
Returns:
|
|
368
|
-
The created
|
|
417
|
+
The created Asset object with the public URL and metadata.
|
|
369
418
|
|
|
370
419
|
Raises:
|
|
371
420
|
NotFoundError: If the user does not exist.
|
|
@@ -379,7 +428,7 @@ class UsersService(BaseService):
|
|
|
379
428
|
self._format_endpoint(Endpoints.USER_ASSET_UPLOAD, user_id=user_id),
|
|
380
429
|
file=(filename, content, content_type),
|
|
381
430
|
)
|
|
382
|
-
return
|
|
431
|
+
return Asset.model_validate(response.json())
|
|
383
432
|
|
|
384
433
|
# -------------------------------------------------------------------------
|
|
385
434
|
# Experience Methods
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/validate_constants.py
RENAMED
|
@@ -77,8 +77,8 @@ CONSTANT_MAP: dict[str, ConstantMapping] = {
|
|
|
77
77
|
"ManageCampaignPermission": ConstantMapping("companies", "PermissionManageCampaign"),
|
|
78
78
|
"PermissionLevel": ConstantMapping("companies", "CompanyPermission"),
|
|
79
79
|
"RollResultType": ConstantMapping("gameplay", "RollResultType"),
|
|
80
|
-
"
|
|
81
|
-
"
|
|
80
|
+
"AssetParentType": ConstantMapping("assets", "AssetParentType"),
|
|
81
|
+
"AssetType": ConstantMapping("assets", "AssetType"),
|
|
82
82
|
"SpecialtyType": ConstantMapping("characters", "SpecialtyType"),
|
|
83
83
|
"TraitModifyCurrency": ConstantMapping("characters", "TraitModifyCurrency"),
|
|
84
84
|
"UserRole": ConstantMapping("users", "UserRole"),
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/campaigns.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/chapters.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/characters.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/companies.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/developers.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/diceroll.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/dictionary.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/global_admin.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/pagination.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/models/system.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/__init__.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/base.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/companies.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/developers.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/dicerolls.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/dictionary.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/global_admin.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/options.py
RENAMED
|
File without changes
|
{valentina_python_client-1.4.0 → valentina_python_client-1.5.0}/src/vclient/services/system.py
RENAMED
|
File without changes
|