valentina-python-client 1.20.1__tar.gz → 1.22.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 (84) hide show
  1. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/PKG-INFO +13 -1
  2. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/README.md +12 -0
  3. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/pyproject.toml +1 -1
  4. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/__init__.py +5 -1
  5. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_codegen.py +5 -0
  6. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/__init__.py +2 -0
  7. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/client.py +15 -0
  8. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/registry.py +24 -0
  9. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/__init__.py +2 -0
  10. valentina_python_client-1.22.0/src/vclient/_sync/services/_audit_params.py +63 -0
  11. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/companies.py +204 -2
  12. valentina_python_client-1.22.0/src/vclient/_sync/services/global_admin.py +406 -0
  13. valentina_python_client-1.22.0/src/vclient/_sync/services/user_lookup.py +68 -0
  14. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/client.py +15 -0
  15. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/constants.py +19 -0
  16. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/endpoints.py +5 -0
  17. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/__init__.py +10 -0
  18. valentina_python_client-1.22.0/src/vclient/models/audit_logs.py +55 -0
  19. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/companies.py +5 -0
  20. valentina_python_client-1.22.0/src/vclient/models/user_lookup.py +22 -0
  21. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/registry.py +24 -0
  22. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/__init__.py +2 -0
  23. valentina_python_client-1.22.0/src/vclient/services/_audit_params.py +64 -0
  24. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/companies.py +207 -3
  25. valentina_python_client-1.22.0/src/vclient/services/global_admin.py +429 -0
  26. valentina_python_client-1.22.0/src/vclient/services/user_lookup.py +67 -0
  27. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/__init__.py +6 -0
  28. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_factories.py +22 -0
  29. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_router.py +9 -0
  30. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_routes.py +8 -0
  31. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/validate_constants.py +2 -0
  32. valentina_python_client-1.20.1/src/vclient/_sync/services/global_admin.py +0 -199
  33. valentina_python_client-1.20.1/src/vclient/services/global_admin.py +0 -217
  34. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/LICENSE +0 -0
  35. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/base.py +0 -0
  36. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/campaign_book_chapters.py +0 -0
  37. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/campaign_books.py +0 -0
  38. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/campaigns.py +0 -0
  39. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/character_autogen.py +0 -0
  40. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/character_blueprint.py +0 -0
  41. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/character_traits.py +0 -0
  42. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/characters.py +0 -0
  43. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/developers.py +0 -0
  44. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/dicerolls.py +0 -0
  45. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/dictionary.py +0 -0
  46. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/options.py +0 -0
  47. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/system.py +0 -0
  48. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/services/users.py +0 -0
  49. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/testing/__init__.py +0 -0
  50. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/_sync/testing/_client.py +0 -0
  51. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/config.py +0 -0
  52. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/exceptions.py +0 -0
  53. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/books.py +0 -0
  54. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/campaigns.py +0 -0
  55. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/chapters.py +0 -0
  56. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/character_autogen.py +0 -0
  57. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/character_blueprint.py +0 -0
  58. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/character_trait.py +0 -0
  59. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/characters.py +0 -0
  60. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/developers.py +0 -0
  61. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/diceroll.py +0 -0
  62. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/dictionary.py +0 -0
  63. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/full_sheet.py +0 -0
  64. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/global_admin.py +0 -0
  65. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/pagination.py +0 -0
  66. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/shared.py +0 -0
  67. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/system.py +0 -0
  68. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/models/users.py +0 -0
  69. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/py.typed +0 -0
  70. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/base.py +0 -0
  71. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/campaign_book_chapters.py +0 -0
  72. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/campaign_books.py +0 -0
  73. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/campaigns.py +0 -0
  74. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/character_autogen.py +0 -0
  75. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/character_blueprint.py +0 -0
  76. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/character_traits.py +0 -0
  77. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/characters.py +0 -0
  78. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/developers.py +0 -0
  79. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/dicerolls.py +0 -0
  80. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/dictionary.py +0 -0
  81. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/options.py +0 -0
  82. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/system.py +0 -0
  83. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/services/users.py +0 -0
  84. {valentina_python_client-1.20.1 → valentina_python_client-1.22.0}/src/vclient/testing/_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: valentina-python-client
3
- Version: 1.20.1
3
+ Version: 1.22.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>
@@ -47,6 +47,18 @@ This client is a supported and up-to-date reference implementation for the [Vale
47
47
 
48
48
  The full documentation is available at https://natelandau.github.io/valentina-python-client/.
49
49
 
50
+ ## Claude Code Skill
51
+
52
+ This repo includes a [Claude Code skill](https://docs.anthropic.com/en/docs/claude-code/skills) that gives Claude deep knowledge of vclient's services, models, constants, and testing utilities. Install it so Claude can help you build applications against the Valentina API.
53
+
54
+ ### Install
55
+
56
+ ```bash
57
+ claude install-skill /path/to/valentina-python-client/vclient-guide-skill
58
+ ```
59
+
60
+ Once installed, Claude will automatically activate the skill when you're working with vclient imports, Valentina API endpoints, or FakeVClient testing.
61
+
50
62
  ## Development Tools
51
63
 
52
64
  ### Validate Constants
@@ -18,6 +18,18 @@ This client is a supported and up-to-date reference implementation for the [Vale
18
18
 
19
19
  The full documentation is available at https://natelandau.github.io/valentina-python-client/.
20
20
 
21
+ ## Claude Code Skill
22
+
23
+ This repo includes a [Claude Code skill](https://docs.anthropic.com/en/docs/claude-code/skills) that gives Claude deep knowledge of vclient's services, models, constants, and testing utilities. Install it so Claude can help you build applications against the Valentina API.
24
+
25
+ ### Install
26
+
27
+ ```bash
28
+ claude install-skill /path/to/valentina-python-client/vclient-guide-skill
29
+ ```
30
+
31
+ Once installed, Claude will automatically activate the skill when you're working with vclient imports, Valentina API endpoints, or FakeVClient testing.
32
+
21
33
  ## Development Tools
22
34
 
23
35
  ### Validate Constants
@@ -16,7 +16,7 @@
16
16
  name = "valentina-python-client"
17
17
  readme = "README.md"
18
18
  requires-python = ">=3.13"
19
- version = "1.20.1"
19
+ version = "1.22.0"
20
20
 
21
21
  [project.optional-dependencies]
22
22
  testing = ["polyfactory>=3.3.0"]
@@ -49,6 +49,7 @@ from vclient._sync import ( # noqa: E402
49
49
  sync_global_admin_service,
50
50
  sync_options_service,
51
51
  sync_system_service,
52
+ sync_user_lookup_service,
52
53
  sync_users_service,
53
54
  )
54
55
  from vclient.client import VClient # noqa: E402
@@ -67,6 +68,7 @@ from vclient.registry import ( # noqa: E402
67
68
  global_admin_service,
68
69
  options_service,
69
70
  system_service,
71
+ user_lookup_service,
70
72
  users_service,
71
73
  )
72
74
 
@@ -100,9 +102,11 @@ __all__ = (
100
102
  "sync_global_admin_service",
101
103
  "sync_options_service",
102
104
  "sync_system_service",
105
+ "sync_user_lookup_service",
103
106
  "sync_users_service",
104
107
  "system_service",
108
+ "user_lookup_service",
105
109
  "users_service",
106
110
  )
107
111
 
108
- __version__ = "1.20.1"
112
+ __version__ = "1.22.0"
@@ -28,6 +28,7 @@ RENAME_CLASSES: dict[str, str] = {
28
28
  "GlobalAdminService": "SyncGlobalAdminService",
29
29
  "OptionsService": "SyncOptionsService",
30
30
  "SystemService": "SyncSystemService",
31
+ "UserLookupService": "SyncUserLookupService",
31
32
  "UsersService": "SyncUsersService",
32
33
  "VClient": "SyncVClient",
33
34
  "FakeVClient": "SyncFakeVClient",
@@ -49,6 +50,7 @@ FACTORY_RENAMES: dict[str, str] = {
49
50
  "dicerolls_service": "sync_dicerolls_service",
50
51
  "options_service": "sync_options_service",
51
52
  "character_autogen_service": "sync_character_autogen_service",
53
+ "user_lookup_service": "sync_user_lookup_service",
52
54
  "configure_default_client": "sync_configure_default_client",
53
55
  "clear_default_client": "sync_clear_default_client",
54
56
  "default_client": "sync_default_client",
@@ -73,6 +75,7 @@ IMPORT_REWRITES: dict[str, str] = {
73
75
  "vclient.services.dicerolls": "vclient._sync.services.dicerolls",
74
76
  "vclient.services.options": "vclient._sync.services.options",
75
77
  "vclient.services.character_autogen": "vclient._sync.services.character_autogen",
78
+ "vclient.services.user_lookup": "vclient._sync.services.user_lookup",
76
79
  "vclient.registry": "vclient._sync.registry",
77
80
  "vclient.testing._client": "vclient._sync.testing._client",
78
81
  }
@@ -307,6 +310,7 @@ def _write_sync_init(path: Path) -> None:
307
310
  " sync_global_admin_service,",
308
311
  " sync_options_service,",
309
312
  " sync_system_service,",
313
+ " sync_user_lookup_service,",
310
314
  " sync_users_service,",
311
315
  ")",
312
316
  "",
@@ -329,6 +333,7 @@ def _write_sync_init(path: Path) -> None:
329
333
  ' "sync_global_admin_service",',
330
334
  ' "sync_options_service",',
331
335
  ' "sync_system_service",',
336
+ ' "sync_user_lookup_service",',
332
337
  ' "sync_users_service",',
333
338
  "]",
334
339
  "",
@@ -19,6 +19,7 @@ from vclient._sync.registry import (
19
19
  sync_global_admin_service,
20
20
  sync_options_service,
21
21
  sync_system_service,
22
+ sync_user_lookup_service,
22
23
  sync_users_service,
23
24
  )
24
25
 
@@ -41,5 +42,6 @@ __all__ = [
41
42
  "sync_global_admin_service",
42
43
  "sync_options_service",
43
44
  "sync_system_service",
45
+ "sync_user_lookup_service",
44
46
  "sync_users_service",
45
47
  ]
@@ -37,6 +37,7 @@ if TYPE_CHECKING:
37
37
  SyncGlobalAdminService,
38
38
  SyncOptionsService,
39
39
  SyncSystemService,
40
+ SyncUserLookupService,
40
41
  SyncUsersService,
41
42
  )
42
43
 
@@ -147,6 +148,7 @@ class SyncVClient:
147
148
  self._developer: SyncDeveloperService | None = None
148
149
  self._global_admin: SyncGlobalAdminService | None = None
149
150
  self._system: SyncSystemService | None = None
151
+ self._user_lookup: SyncUserLookupService | None = None
150
152
  if set_as_default:
151
153
  from vclient._sync.registry import sync_configure_default_client
152
154
 
@@ -278,6 +280,19 @@ class SyncVClient:
278
280
  self._system = SyncSystemService(self)
279
281
  return self._system
280
282
 
283
+ @property
284
+ def user_lookup(self) -> "SyncUserLookupService":
285
+ """Access the User Lookup service for cross-company user discovery.
286
+
287
+ Returns:
288
+ The SyncUserLookupService instance for user lookup operations.
289
+ """
290
+ if self._user_lookup is None:
291
+ from vclient._sync.services.user_lookup import SyncUserLookupService
292
+
293
+ self._user_lookup = SyncUserLookupService(self)
294
+ return self._user_lookup
295
+
281
296
  def users(self, company_id: str | None = None) -> "SyncUsersService":
282
297
  """Get a SyncUsersService scoped to a specific company.
283
298
 
@@ -38,6 +38,7 @@ if TYPE_CHECKING:
38
38
  SyncGlobalAdminService,
39
39
  SyncOptionsService,
40
40
  SyncSystemService,
41
+ SyncUserLookupService,
41
42
  SyncUsersService,
42
43
  )
43
44
  _default_client: "SyncVClient | None" = None
@@ -189,6 +190,29 @@ def sync_system_service() -> "SyncSystemService":
189
190
  return SyncSystemService(sync_default_client())
190
191
 
191
192
 
193
+ def sync_user_lookup_service() -> "SyncUserLookupService":
194
+ """Create a SyncUserLookupService using the default client.
195
+
196
+ Discover which companies a person has a user record in by searching
197
+ via email, Discord ID, Google ID, or GitHub ID.
198
+
199
+ Returns:
200
+ SyncUserLookupService: A service instance for cross-company user lookup.
201
+
202
+ Raises:
203
+ RuntimeError: If no default client has been configured.
204
+
205
+ Example:
206
+ ```python
207
+ lookup = sync_user_lookup_service()
208
+ results = await lookup.by_email("alice@example.com")
209
+ ```
210
+ """
211
+ from vclient._sync.services.user_lookup import SyncUserLookupService
212
+
213
+ return SyncUserLookupService(sync_default_client())
214
+
215
+
192
216
  def sync_users_service(company_id: str | None = None) -> "SyncUsersService":
193
217
  """Create a SyncUsersService scoped to a specific company using the default client.
194
218
 
@@ -16,6 +16,7 @@ from .dictionary import SyncDictionaryService
16
16
  from .global_admin import SyncGlobalAdminService
17
17
  from .options import SyncOptionsService
18
18
  from .system import SyncSystemService
19
+ from .user_lookup import SyncUserLookupService
19
20
  from .users import SyncUsersService
20
21
 
21
22
  __all__ = [
@@ -34,5 +35,6 @@ __all__ = [
34
35
  "SyncGlobalAdminService",
35
36
  "SyncOptionsService",
36
37
  "SyncSystemService",
38
+ "SyncUserLookupService",
37
39
  "SyncUsersService",
38
40
  ]
@@ -0,0 +1,63 @@
1
+ # AUTO-GENERATED — do not edit. Run 'uv run duty generate_sync' to regenerate.
2
+ """Shared query parameter builder for audit log endpoints."""
3
+
4
+ from collections.abc import Sequence
5
+ from datetime import datetime
6
+
7
+
8
+ def _build_audit_params(
9
+ *,
10
+ acting_user_id: str | None = None,
11
+ user_id: str | None = None,
12
+ campaign_id: str | None = None,
13
+ book_id: str | None = None,
14
+ chapter_id: str | None = None,
15
+ character_id: str | None = None,
16
+ entity_type: str | None = None,
17
+ operation: str | None = None,
18
+ date_from: datetime | None = None,
19
+ date_to: datetime | None = None,
20
+ include: Sequence[str] | None = None,
21
+ company_id: str | None = None,
22
+ ) -> dict[str, str]:
23
+ """Build query parameter dict from audit log filter kwargs.
24
+
25
+ Only include non-None values. Serialize datetimes to ISO 8601 and
26
+ join include lists with commas.
27
+
28
+ Args:
29
+ acting_user_id: Filter by the user who performed the action.
30
+ user_id: Filter by the user affected by the action.
31
+ campaign_id: Filter by campaign ID.
32
+ book_id: Filter by book ID.
33
+ chapter_id: Filter by chapter ID.
34
+ character_id: Filter by character ID.
35
+ entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
36
+ operation: Filter by operation type (CREATE, UPDATE, DELETE).
37
+ date_from: Return logs on or after this datetime (ISO 8601 serialized).
38
+ date_to: Return logs on or before this datetime (ISO 8601 serialized).
39
+ include: Additional data to include (e.g., ("request_details",)).
40
+ company_id: Filter by company ID (used for global admin endpoint).
41
+
42
+ Returns:
43
+ A dict of query parameters with only non-None values included.
44
+ """
45
+ string_params: dict[str, str | None] = {
46
+ "acting_user_id": acting_user_id,
47
+ "user_id": user_id,
48
+ "campaign_id": campaign_id,
49
+ "book_id": book_id,
50
+ "chapter_id": chapter_id,
51
+ "character_id": character_id,
52
+ "entity_type": entity_type,
53
+ "operation": operation,
54
+ "company_id": company_id,
55
+ }
56
+ params: dict[str, str] = {k: v for k, v in string_params.items() if v is not None}
57
+ if date_from is not None:
58
+ params["date_from"] = date_from.isoformat()
59
+ if date_to is not None:
60
+ params["date_to"] = date_to.isoformat()
61
+ if include is not None:
62
+ params["include"] = ",".join(include)
63
+ return params
@@ -1,12 +1,21 @@
1
1
  # AUTO-GENERATED — do not edit. Run 'uv run duty generate_sync' to regenerate.
2
2
  """Service for interacting with the Companies API."""
3
3
 
4
- from collections.abc import Iterator
4
+ from collections.abc import Iterator, Sequence
5
+ from datetime import datetime
5
6
 
6
7
  from vclient._sync.services.base import SyncBaseService
7
- from vclient.constants import DEFAULT_PAGE_LIMIT, PermissionLevel
8
+ from vclient.constants import (
9
+ DEFAULT_PAGE_LIMIT,
10
+ AuditEntityType,
11
+ AuditLogInclude,
12
+ AuditOperation,
13
+ PermissionLevel,
14
+ )
8
15
  from vclient.endpoints import Endpoints
9
16
  from vclient.models import (
17
+ AuditLog,
18
+ AuditLogDetail,
10
19
  Company,
11
20
  CompanyCreate,
12
21
  CompanyPermissions,
@@ -16,6 +25,7 @@ from vclient.models import (
16
25
  RollStatistics,
17
26
  _GrantAccess,
18
27
  )
28
+ from vclient.services._audit_params import _build_audit_params
19
29
 
20
30
 
21
31
  class SyncCompaniesService(SyncBaseService):
@@ -216,3 +226,195 @@ class SyncCompaniesService(SyncBaseService):
216
226
  params={"num_top_traits": num_top_traits},
217
227
  )
218
228
  return RollStatistics.model_validate(response.json())
229
+
230
+ def get_audit_log_page(
231
+ self,
232
+ company_id: str,
233
+ *,
234
+ limit: int = DEFAULT_PAGE_LIMIT,
235
+ offset: int = 0,
236
+ acting_user_id: str | None = None,
237
+ user_id: str | None = None,
238
+ campaign_id: str | None = None,
239
+ book_id: str | None = None,
240
+ chapter_id: str | None = None,
241
+ character_id: str | None = None,
242
+ entity_type: AuditEntityType | None = None,
243
+ operation: AuditOperation | None = None,
244
+ date_from: datetime | None = None,
245
+ date_to: datetime | None = None,
246
+ include: Sequence[AuditLogInclude] | None = None,
247
+ ) -> PaginatedResponse[AuditLog] | PaginatedResponse[AuditLogDetail]:
248
+ """Retrieve a paginated page of audit log entries for a company.
249
+
250
+ Use filter parameters to narrow results by entity, operation, user, or time range.
251
+ Pass ``include=["request_details"]`` to receive full HTTP request forensics in each
252
+ entry (returns AuditLogDetail instead of AuditLog).
253
+
254
+ Args:
255
+ company_id: The ID of the company whose audit logs to retrieve.
256
+ limit: Maximum number of items to return (0-100, default 10).
257
+ offset: Number of items to skip from the beginning (default 0).
258
+ acting_user_id: Filter by the user who performed the action.
259
+ user_id: Filter by the user affected by the action.
260
+ campaign_id: Filter by campaign ID.
261
+ book_id: Filter by book ID.
262
+ chapter_id: Filter by chapter ID.
263
+ character_id: Filter by character ID.
264
+ entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
265
+ operation: Filter by operation type (CREATE, UPDATE, DELETE).
266
+ date_from: Return logs on or after this datetime.
267
+ date_to: Return logs on or before this datetime.
268
+ include: Additional data to include. Pass ["request_details"] for HTTP forensics.
269
+
270
+ Returns:
271
+ A PaginatedResponse containing AuditLog (or AuditLogDetail) objects.
272
+
273
+ Raises:
274
+ NotFoundError: If the company does not exist.
275
+ AuthorizationError: If you don't have access to the company.
276
+ """
277
+ model = AuditLogDetail if include and "request_details" in include else AuditLog
278
+ params = _build_audit_params(
279
+ acting_user_id=acting_user_id,
280
+ user_id=user_id,
281
+ campaign_id=campaign_id,
282
+ book_id=book_id,
283
+ chapter_id=chapter_id,
284
+ character_id=character_id,
285
+ entity_type=entity_type,
286
+ operation=operation,
287
+ date_from=date_from,
288
+ date_to=date_to,
289
+ include=include,
290
+ )
291
+ return self._get_paginated_as(
292
+ Endpoints.COMPANY_AUDIT_LOGS.format(company_id=company_id),
293
+ model,
294
+ limit=limit,
295
+ offset=offset,
296
+ params=params,
297
+ )
298
+
299
+ def list_all_audit_logs(
300
+ self,
301
+ company_id: str,
302
+ *,
303
+ acting_user_id: str | None = None,
304
+ user_id: str | None = None,
305
+ campaign_id: str | None = None,
306
+ book_id: str | None = None,
307
+ chapter_id: str | None = None,
308
+ character_id: str | None = None,
309
+ entity_type: AuditEntityType | None = None,
310
+ operation: AuditOperation | None = None,
311
+ date_from: datetime | None = None,
312
+ date_to: datetime | None = None,
313
+ include: Sequence[AuditLogInclude] | None = None,
314
+ ) -> list[AuditLog] | list[AuditLogDetail]:
315
+ """Retrieve all audit log entries for a company.
316
+
317
+ Automatically paginates through all results. Use ``get_audit_log_page()`` for
318
+ paginated access or ``iter_all_audit_logs()`` for memory-efficient streaming.
319
+
320
+ Args:
321
+ company_id: The ID of the company whose audit logs to retrieve.
322
+ acting_user_id: Filter by the user who performed the action.
323
+ user_id: Filter by the user affected by the action.
324
+ campaign_id: Filter by campaign ID.
325
+ book_id: Filter by book ID.
326
+ chapter_id: Filter by chapter ID.
327
+ character_id: Filter by character ID.
328
+ entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
329
+ operation: Filter by operation type (CREATE, UPDATE, DELETE).
330
+ date_from: Return logs on or after this datetime.
331
+ date_to: Return logs on or before this datetime.
332
+ include: Additional data to include. Pass ["request_details"] for HTTP forensics.
333
+
334
+ Returns:
335
+ A list of all AuditLog (or AuditLogDetail) objects.
336
+
337
+ Raises:
338
+ NotFoundError: If the company does not exist.
339
+ AuthorizationError: If you don't have access to the company.
340
+ """
341
+ return [
342
+ log
343
+ for log in self.iter_all_audit_logs(
344
+ company_id,
345
+ acting_user_id=acting_user_id,
346
+ user_id=user_id,
347
+ campaign_id=campaign_id,
348
+ book_id=book_id,
349
+ chapter_id=chapter_id,
350
+ character_id=character_id,
351
+ entity_type=entity_type,
352
+ operation=operation,
353
+ date_from=date_from,
354
+ date_to=date_to,
355
+ include=include,
356
+ )
357
+ ]
358
+
359
+ def iter_all_audit_logs(
360
+ self,
361
+ company_id: str,
362
+ *,
363
+ limit: int = 100,
364
+ acting_user_id: str | None = None,
365
+ user_id: str | None = None,
366
+ campaign_id: str | None = None,
367
+ book_id: str | None = None,
368
+ chapter_id: str | None = None,
369
+ character_id: str | None = None,
370
+ entity_type: AuditEntityType | None = None,
371
+ operation: AuditOperation | None = None,
372
+ date_from: datetime | None = None,
373
+ date_to: datetime | None = None,
374
+ include: Sequence[AuditLogInclude] | None = None,
375
+ ) -> Iterator[AuditLog] | Iterator[AuditLogDetail]:
376
+ """Iterate through all audit log entries for a company.
377
+
378
+ Yields individual audit log entries, automatically fetching subsequent pages
379
+ until all matching entries have been retrieved.
380
+
381
+ Args:
382
+ company_id: The ID of the company whose audit logs to retrieve.
383
+ limit: Items per page (default 100 for efficiency).
384
+ acting_user_id: Filter by the user who performed the action.
385
+ user_id: Filter by the user affected by the action.
386
+ campaign_id: Filter by campaign ID.
387
+ book_id: Filter by book ID.
388
+ chapter_id: Filter by chapter ID.
389
+ character_id: Filter by character ID.
390
+ entity_type: Filter by entity type (e.g., "CAMPAIGN", "CHARACTER").
391
+ operation: Filter by operation type (CREATE, UPDATE, DELETE).
392
+ date_from: Return logs on or after this datetime.
393
+ date_to: Return logs on or before this datetime.
394
+ include: Additional data to include. Pass ["request_details"] for HTTP forensics.
395
+
396
+ Yields:
397
+ Individual AuditLog (or AuditLogDetail) objects.
398
+
399
+ Raises:
400
+ NotFoundError: If the company does not exist.
401
+ AuthorizationError: If you don't have access to the company.
402
+ """
403
+ model = AuditLogDetail if include and "request_details" in include else AuditLog
404
+ params = _build_audit_params(
405
+ acting_user_id=acting_user_id,
406
+ user_id=user_id,
407
+ campaign_id=campaign_id,
408
+ book_id=book_id,
409
+ chapter_id=chapter_id,
410
+ character_id=character_id,
411
+ entity_type=entity_type,
412
+ operation=operation,
413
+ date_from=date_from,
414
+ date_to=date_to,
415
+ include=include,
416
+ )
417
+ for item in self._iter_all_pages(
418
+ Endpoints.COMPANY_AUDIT_LOGS.format(company_id=company_id), limit=limit, params=params
419
+ ):
420
+ yield model.model_validate(item)