valentina-python-client 1.3.1__tar.gz → 1.4.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.
Files changed (47) hide show
  1. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/PKG-INFO +1 -1
  2. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/pyproject.toml +1 -1
  3. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/__init__.py +1 -1
  4. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/client.py +0 -1
  5. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/base.py +1 -1
  6. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/campaign_book_chapters.py +6 -2
  7. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/campaign_books.py +6 -2
  8. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/campaigns.py +6 -2
  9. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/character_traits.py +1 -1
  10. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/characters.py +6 -2
  11. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/users.py +6 -2
  12. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/LICENSE +0 -0
  13. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/README.md +0 -0
  14. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/config.py +0 -0
  15. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/constants.py +0 -0
  16. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/endpoints.py +0 -0
  17. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/exceptions.py +0 -0
  18. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/__init__.py +0 -0
  19. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/books.py +0 -0
  20. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/campaigns.py +0 -0
  21. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/chapters.py +0 -0
  22. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/character_autogen.py +0 -0
  23. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/character_blueprint.py +0 -0
  24. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/character_trait.py +0 -0
  25. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/characters.py +0 -0
  26. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/companies.py +0 -0
  27. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/developers.py +0 -0
  28. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/diceroll.py +0 -0
  29. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/dictionary.py +0 -0
  30. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/global_admin.py +0 -0
  31. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/pagination.py +0 -0
  32. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/shared.py +0 -0
  33. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/system.py +0 -0
  34. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/models/users.py +0 -0
  35. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/py.typed +0 -0
  36. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/registry.py +0 -0
  37. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/__init__.py +0 -0
  38. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/character_autogen.py +0 -0
  39. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/character_blueprint.py +0 -0
  40. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/companies.py +0 -0
  41. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/developers.py +0 -0
  42. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/dicerolls.py +0 -0
  43. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/dictionary.py +0 -0
  44. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/global_admin.py +0 -0
  45. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/options.py +0 -0
  46. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/services/system.py +0 -0
  47. {valentina_python_client-1.3.1 → valentina_python_client-1.4.0}/src/vclient/validate_constants.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: valentina-python-client
3
- Version: 1.3.1
3
+ Version: 1.4.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>
@@ -10,7 +10,7 @@
10
10
  name = "valentina-python-client"
11
11
  readme = "README.md"
12
12
  requires-python = ">=3.13"
13
- version = "1.3.1"
13
+ version = "1.4.0"
14
14
 
15
15
  [project.urls]
16
16
  Homepage = "https://docs.valentina-noir.com/python-api-client/"
@@ -71,4 +71,4 @@ __all__ = (
71
71
  "users_service",
72
72
  )
73
73
 
74
- __version__ = "1.3.1"
74
+ __version__ = "1.4.0"
@@ -170,7 +170,6 @@ class VClient:
170
170
 
171
171
  headers = {
172
172
  "Accept": "application/json",
173
- "Content-Type": "application/json",
174
173
  "User-Agent": user_agent,
175
174
  **self._config.headers,
176
175
  }
@@ -577,7 +577,7 @@ class BaseService:
577
577
  return await self._request(
578
578
  "POST",
579
579
  path,
580
- files={"file": (filename, content, content_type)},
580
+ files={"data": (filename, content, content_type)},
581
581
  headers=self._build_idempotency_headers(idempotency_key),
582
582
  )
583
583
 
@@ -1,5 +1,6 @@
1
1
  """Service for interacting with the Campaign Books Chapters API."""
2
2
 
3
+ import mimetypes
3
4
  from collections.abc import AsyncIterator
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -399,7 +400,7 @@ class ChaptersService(BaseService):
399
400
  chapter_id: str,
400
401
  filename: str,
401
402
  content: bytes,
402
- content_type: str = "application/octet-stream",
403
+ content_type: str | None = None,
403
404
  ) -> S3Asset:
404
405
  """Upload a new asset for a chapter.
405
406
 
@@ -409,7 +410,7 @@ class ChaptersService(BaseService):
409
410
  chapter_id: The ID of the chapter to upload the asset for.
410
411
  filename: The original filename of the asset.
411
412
  content: The raw bytes of the file to upload.
412
- content_type: The MIME type of the file (default: application/octet-stream).
413
+ content_type: The MIME type of the file. If not provided, inferred from filename.
413
414
 
414
415
  Returns:
415
416
  The created S3Asset object with the public URL and metadata.
@@ -419,6 +420,9 @@ class ChaptersService(BaseService):
419
420
  AuthorizationError: If you don't have appropriate access.
420
421
  ValidationError: If the file is invalid or exceeds size limits.
421
422
  """
423
+ if content_type is None:
424
+ content_type = mimetypes.guess_type(filename)[0] or "application/octet-stream"
425
+
422
426
  response = await self._post_file(
423
427
  self._format_endpoint(Endpoints.BOOK_CHAPTER_ASSET_UPLOAD, chapter_id=chapter_id),
424
428
  file=(filename, content, content_type),
@@ -1,5 +1,6 @@
1
1
  """Service for interacting with the Campaign Books API."""
2
2
 
3
+ import mimetypes
3
4
  from collections.abc import AsyncIterator
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -493,7 +494,7 @@ class BooksService(BaseService):
493
494
  book_id: str,
494
495
  filename: str,
495
496
  content: bytes,
496
- content_type: str = "application/octet-stream",
497
+ content_type: str | None = None,
497
498
  ) -> S3Asset:
498
499
  """Upload a new asset for a book.
499
500
 
@@ -503,7 +504,7 @@ class BooksService(BaseService):
503
504
  book_id: The ID of the book to upload the asset for.
504
505
  filename: The original filename of the asset.
505
506
  content: The raw bytes of the file to upload.
506
- content_type: The MIME type of the file (default: application/octet-stream).
507
+ content_type: The MIME type of the file. If not provided, inferred from filename.
507
508
 
508
509
  Returns:
509
510
  The created S3Asset object with the public URL and metadata.
@@ -513,6 +514,9 @@ class BooksService(BaseService):
513
514
  AuthorizationError: If you don't have appropriate access.
514
515
  ValidationError: If the file is invalid or exceeds size limits.
515
516
  """
517
+ if content_type is None:
518
+ content_type = mimetypes.guess_type(filename)[0] or "application/octet-stream"
519
+
516
520
  response = await self._post_file(
517
521
  self._format_endpoint(Endpoints.BOOK_ASSET_UPLOAD, book_id=book_id),
518
522
  file=(filename, content, content_type),
@@ -1,5 +1,6 @@
1
1
  """Service for interacting with the Campaigns API."""
2
2
 
3
+ import mimetypes
3
4
  from collections.abc import AsyncIterator
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -329,7 +330,7 @@ class CampaignsService(BaseService):
329
330
  campaign_id: str,
330
331
  filename: str,
331
332
  content: bytes,
332
- content_type: str = "application/octet-stream",
333
+ content_type: str | None = None,
333
334
  ) -> S3Asset:
334
335
  """Upload a new asset for a campaign.
335
336
 
@@ -339,7 +340,7 @@ class CampaignsService(BaseService):
339
340
  campaign_id: The ID of the campaign to upload the asset for.
340
341
  filename: The original filename of the asset.
341
342
  content: The raw bytes of the file to upload.
342
- content_type: The MIME type of the file (default: application/octet-stream).
343
+ content_type: The MIME type of the file. If not provided, inferred from filename.
343
344
 
344
345
  Returns:
345
346
  The created S3Asset object with the public URL and metadata.
@@ -349,6 +350,9 @@ class CampaignsService(BaseService):
349
350
  AuthorizationError: If you don't have appropriate access.
350
351
  ValidationError: If the file is invalid or exceeds size limits.
351
352
  """
353
+ if content_type is None:
354
+ content_type = mimetypes.guess_type(filename)[0] or "application/octet-stream"
355
+
352
356
  response = await self._post_file(
353
357
  self._format_endpoint(Endpoints.CAMPAIGN_ASSET_UPLOAD, campaign_id=campaign_id),
354
358
  file=(filename, content, content_type),
@@ -178,7 +178,7 @@ class CharacterTraitsService(BaseService):
178
178
  value=value,
179
179
  )
180
180
  response = await self._post(
181
- self._format_endpoint(Endpoints.CHARACTER_TRAIT_CREATE),
181
+ self._format_endpoint(Endpoints.CHARACTER_TRAIT_ASSIGN),
182
182
  json=body.model_dump(exclude_none=True, exclude_unset=True, mode="json"),
183
183
  )
184
184
  return CharacterTrait.model_validate(response.json())
@@ -1,5 +1,6 @@
1
1
  """Service for interacting with the Characters API."""
2
2
 
3
+ import mimetypes
3
4
  from collections.abc import AsyncIterator
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -413,7 +414,7 @@ class CharactersService(BaseService):
413
414
  character_id: str,
414
415
  filename: str,
415
416
  content: bytes,
416
- content_type: str = "application/octet-stream",
417
+ content_type: str | None = None,
417
418
  ) -> S3Asset:
418
419
  """Upload a new asset for a campaign.
419
420
 
@@ -423,7 +424,7 @@ class CharactersService(BaseService):
423
424
  character_id: The ID of the character to upload the asset for.
424
425
  filename: The original filename of the asset.
425
426
  content: The raw bytes of the file to upload.
426
- content_type: The MIME type of the file (default: application/octet-stream).
427
+ content_type: The MIME type of the file. If not provided, inferred from filename.
427
428
 
428
429
  Returns:
429
430
  The created S3Asset object with the public URL and metadata.
@@ -433,6 +434,9 @@ class CharactersService(BaseService):
433
434
  AuthorizationError: If you don't have appropriate access.
434
435
  ValidationError: If the file is invalid or exceeds size limits.
435
436
  """
437
+ if content_type is None:
438
+ content_type = mimetypes.guess_type(filename)[0] or "application/octet-stream"
439
+
436
440
  response = await self._post_file(
437
441
  self._format_endpoint(Endpoints.CHARACTER_ASSET_UPLOAD, character_id=character_id),
438
442
  file=(filename, content, content_type),
@@ -1,5 +1,6 @@
1
1
  """Service for interacting with the Users API."""
2
2
 
3
+ import mimetypes
3
4
  from collections.abc import AsyncIterator
4
5
  from typing import TYPE_CHECKING
5
6
 
@@ -351,7 +352,7 @@ class UsersService(BaseService):
351
352
  user_id: str,
352
353
  filename: str,
353
354
  content: bytes,
354
- content_type: str = "application/octet-stream",
355
+ content_type: str | None = None,
355
356
  ) -> S3Asset:
356
357
  """Upload a new asset for a user.
357
358
 
@@ -361,7 +362,7 @@ class UsersService(BaseService):
361
362
  user_id: The ID of the user to upload the asset for.
362
363
  filename: The original filename of the asset.
363
364
  content: The raw bytes of the file to upload.
364
- content_type: The MIME type of the file (default: application/octet-stream).
365
+ content_type: The MIME type of the file. If not provided, inferred from filename.
365
366
 
366
367
  Returns:
367
368
  The created S3Asset object with the public URL and metadata.
@@ -371,6 +372,9 @@ class UsersService(BaseService):
371
372
  AuthorizationError: If you don't have appropriate access.
372
373
  ValidationError: If the file is invalid or exceeds size limits.
373
374
  """
375
+ if content_type is None:
376
+ content_type = mimetypes.guess_type(filename)[0] or "application/octet-stream"
377
+
374
378
  response = await self._post_file(
375
379
  self._format_endpoint(Endpoints.USER_ASSET_UPLOAD, user_id=user_id),
376
380
  file=(filename, content, content_type),